home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / bin / xtras / parse.c < prev    next >
C/C++ Source or Header  |  1994-09-11  |  87KB  |  3,349 lines

  1. /****************************************************************************
  2. *
  3. *  ATTENTION!!!
  4. *
  5. *  THIS FILE HAS BEEN MODIFIED!!! IT IS NOT PART OF THE OFFICAL
  6. *  POV-RAY 2.2 DISTRIBUTION!!!
  7. *
  8. *  THIS FILE IS PART OF "FASTER THAN POV-RAY" (VERSION 2.2),
  9. *  A SPED-UP VERSION OF POV-RAY 2.2. USE AT YOUR OWN RISK!!!!!!
  10. *
  11. *  New files: addon0.c, addon1.c, addon2.c, addon3.c, addon.h
  12. *
  13. *  The additional modules were written by Dieter Bayer.
  14. *
  15. *  Send comments, suggestions, bugs, ideas ... to:
  16. *
  17. *  e-mail: dieter@cip.e-technik.uni-erlangen.de
  18. *  CIS: 100255.3074
  19. *
  20. *  All changed/added lines are enclosed in #ifdef DB_CODE ... #endif
  21. *
  22. *  The vista projection was taken from:
  23. *
  24. *    A. Hashimoto, T. Akimoto, K. Mase, and Y. Suenaga, 
  25. *    "Vista Ray-Tracing: High Speed Ray Tracing Using Perspective
  26. *    Projection Image", New Advances in Computer Graphics, Proceedings
  27. *    of CG International '89, R. A. Earnshaw, B. Wyvill (Eds.), 
  28. *    Springer, ..., pp. 549-560
  29. *
  30. *  The idea for the light buffer was taken from:
  31. *
  32. *    E. Haines and D. Greenberg, "The Light Buffer: A Shadow-Testing 
  33. *    Accelerator", IEEE CG&A, Vol. 6, No. 9, Sept. 1986, pp. 6-16
  34. *
  35. *****************************************************************************/
  36.  
  37. /****************************************************************************
  38. *                parse.c
  39. *
  40. *  This module implements a parser for the scene description files.
  41. *
  42. *  from Persistence of Vision Raytracer
  43. *  Copyright 1993 Persistence of Vision Team
  44. *---------------------------------------------------------------------------
  45. *  NOTICE: This source code file is provided so that users may experiment
  46. *  with enhancements to POV-Ray and to port the software to platforms other 
  47. *  than those supported by the POV-Ray Team.  There are strict rules under
  48. *  which you are permitted to use this file.  The rules are in the file
  49. *  named POVLEGAL.DOC which should be distributed with this file. If 
  50. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  51. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  52. *  Forum.  The latest version of POV-Ray may be found there as well.
  53. *
  54. * This program is based on the popular DKB raytracer version 2.12.
  55. * DKBTrace was originally written by David K. Buck.
  56. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  57. *
  58. *****************************************************************************/
  59.  
  60. #include "frame.h"
  61. #include "vector.h"
  62. #include "povproto.h"
  63. #include "parse.h"
  64.  
  65. /* This file implements a simple recursive-descent parser for reading the
  66. input file.  */
  67.  
  68. extern DBL Max_Trace_Level;
  69. extern char VerboseFormat;
  70. extern unsigned int Options;
  71. extern int Use_Slabs;
  72. extern char Stat_File_Name[FILE_NAME_LENGTH];
  73.  
  74. extern struct Reserved_Word_Struct Reserved_Words [];
  75. extern DBL Antialias_Threshold;
  76.  
  77. extern struct Token_Struct Token;
  78. extern char String[MAX_STRING_INDEX];
  79.  
  80. extern COLOUR_MAP_ENTRY *Build_Entries;
  81. extern FRAME Frame;
  82. extern DBL Clock_Value;
  83. extern char **Symbol_Table;
  84. extern int Max_Intersections;
  85. extern DBL Language_Version;
  86. extern METHODS Csg_Height_Field_Methods;
  87. extern METHODS CSG_Union_Methods;
  88. #ifdef DB_CODE
  89. /* necessary for bounding of quadrics. */
  90. extern METHODS Quadric_Methods;
  91. #endif
  92.  
  93. static void Parse_Image_Map PARAMS((PIGMENT *Pigment));
  94. static void Parse_Bump_Map PARAMS((TNORMAL *Tnormal));
  95. static void Parse_Pigment PARAMS((PIGMENT **Pigment_Ptr));
  96. static void Parse_Tnormal PARAMS((TNORMAL **Tnormal_Ptr));
  97. static void Parse_Finish PARAMS((FINISH **Finish_Ptr));
  98. static TEXTURE *Parse_Texture PARAMS((void));
  99. static void Token_Init PARAMS((void));
  100. static void Frame_Init PARAMS((void));
  101. static void Parse_Coeffs PARAMS((int order, DBL *Coeffs));
  102. static IMAGE *Parse_Image PARAMS((int Legal));
  103. static TRANSFORM *Parse_Transform PARAMS((void));
  104. static void Parse_Object_Mods PARAMS((OBJECT *Object));
  105. static OBJECT *Parse_Bicubic_Patch PARAMS((void));
  106. static OBJECT *Parse_Blob PARAMS((void));
  107. static OBJECT *Parse_Box PARAMS((void));
  108. static OBJECT *Parse_Cone PARAMS((void));
  109. static OBJECT *Parse_Cylinder PARAMS((void));
  110. static OBJECT *Parse_Disc PARAMS((void));
  111. static OBJECT *Parse_Height_Field PARAMS((void));
  112. static OBJECT *Parse_Plane PARAMS((void));
  113. static OBJECT *Parse_Poly PARAMS((int order));
  114. static OBJECT *Parse_Quadric PARAMS((void));
  115. static OBJECT *Parse_Smooth_Triangle PARAMS((void));
  116. static OBJECT *Parse_Sphere PARAMS((void));
  117. static OBJECT *Parse_Torus PARAMS((void));
  118. static OBJECT *Parse_Triangle PARAMS((void));
  119. static OBJECT *Parse_CSG PARAMS((int CSG_Type));
  120. static OBJECT *Parse_Light_Source PARAMS((void));
  121. static OBJECT *Parse_Object PARAMS((void));
  122. static void Parse_Fog PARAMS((void));
  123. static void Parse_Frame PARAMS((void));
  124. static void Parse_Camera PARAMS((CAMERA **Camera_Ptr));
  125. static void Parse_Declare PARAMS((void));
  126. static void Link PARAMS((OBJECT *New_Object,OBJECT **Field,OBJECT **Old_Object_List));
  127. static void Link_Textures PARAMS((TEXTURE **Old_Texture, TEXTURE *New_Texture));
  128. static char *Get_Token_String PARAMS((TOKEN Token_Id));
  129. static void Where_Error PARAMS((void));
  130. static int Test_Redefine PARAMS((int a));
  131. static OBJECT *Parse_Bound_Clip PARAMS((void));
  132. static void Found_Instead PARAMS((void));
  133. /*static void Parse_Warn PARAMS((TOKEN Token_Id));*/
  134. static void Warn_State PARAMS((TOKEN Token_Id, TOKEN Type));
  135. static void Post_Process PARAMS((OBJECT *Object, OBJECT *Parent));
  136. static void Destroy_Constants PARAMS((void));
  137. static OBJECT *Parse_Object_Id PARAMS((void));
  138. static void Link_To_Frame PARAMS((OBJECT *Object));
  139.  
  140. extern struct Constant_Struct Constants[MAX_CONSTANTS];
  141.  
  142. int Number_Of_Constants;
  143. int Previous;
  144. short Have_Vector;
  145. short Not_In_Default;
  146.  
  147. TOKEN *Brace_Stack;
  148. int Brace_Index;
  149.  
  150. TEXTURE *Default_Texture;
  151. CAMERA *Default_Camera;
  152.  
  153. /* Parse the file. */
  154. void Parse ()
  155.   {
  156.    Build_Entries  = NULL;
  157.    if ((Brace_Stack = (TOKEN *) malloc(MAX_BRACES*sizeof (TOKEN))) == NULL)
  158.      MAError ("brace stack");
  159.    Brace_Index = 0;
  160.    Token_Init ();
  161.    Default_Camera = Create_Camera();
  162.    Default_Texture = Create_PNF_Texture();
  163.    Default_Texture->Pigment = Create_Pigment();
  164.    Default_Texture->Tnormal = NULL;
  165.    Default_Texture->Finish  = Create_Finish();
  166.    Not_In_Default = TRUE;
  167.    Frame_Init ();
  168.    Parse_Frame ();
  169.    if (Frame.Objects==NULL)
  170.      Error("No objects in scene");
  171.    Destroy_Constants ();
  172.    Destroy_Textures(Default_Texture);
  173.    Destroy_Camera(Default_Camera);
  174.    if (Build_Entries != NULL)
  175.      free (Build_Entries);
  176.    free (Brace_Stack);
  177.   }
  178.  
  179. static void Token_Init ()
  180.   {
  181.    Number_Of_Constants = 0;
  182.   }
  183.  
  184. /* Set up the fields in the frame to default values. */
  185. static
  186. void Frame_Init ()
  187.   {
  188.    Frame.Camera = Copy_Camera(Default_Camera);
  189.    Frame.Light_Sources = NULL;
  190.    Frame.Objects = NULL;
  191.    Frame.Atmosphere_IOR = 1.0;
  192.    Frame.Antialias_Threshold = Antialias_Threshold;
  193.    Frame.Fog_Distance = 0.0;
  194.    Make_Colour (&(Frame.Fog_Colour), 0.0, 0.0, 0.0);
  195.   }
  196.  
  197. void Parse_Begin ()
  198.   {
  199.    char *front;
  200.  
  201.    Brace_Stack[++Brace_Index]=Token.Token_Id;
  202.    Get_Token ();
  203.  
  204.    if (Token.Token_Id == LEFT_CURLY_TOKEN)
  205.      return;
  206.  
  207.    Where_Error ();
  208.  
  209.    front = Get_Token_String (Brace_Stack[Brace_Index]);
  210.    fprintf (stderr, "Missing { after %s, ", front);
  211.    Found_Instead ();
  212.    exit (1);
  213.   }
  214.  
  215. void Parse_End ()
  216.   {
  217.    char *front;
  218.  
  219.    Get_Token ();
  220.  
  221.    if (Token.Token_Id == RIGHT_CURLY_TOKEN)
  222.      {
  223.       Brace_Index--;
  224.       return;
  225.      }
  226.  
  227.    Where_Error ();
  228.  
  229.    front = Get_Token_String (Brace_Stack[Brace_Index]);
  230.    fprintf (stderr, "No matching } in %s,", front);
  231.    Found_Instead ();
  232.    exit (1);
  233.   }
  234.  
  235. static OBJECT *Parse_Object_Id ()
  236.   {
  237.    OBJECT *Object;
  238.    
  239.    EXPECT
  240.      CASE (OBJECT_ID_TOKEN)
  241.        Warn_State(OBJECT_ID_TOKEN, OBJECT_TOKEN);
  242.        Object = Copy_Object((OBJECT *) Token.Constant_Data);
  243.        Parse_Object_Mods (Object);
  244.        EXIT
  245.      END_CASE
  246.  
  247.      OTHERWISE
  248.        Object = NULL;
  249.        UNGET
  250.        EXIT
  251.      END_CASE
  252.    END_EXPECT
  253.  
  254.    return (Object);
  255.   }
  256.  
  257. void Parse_Comma ()
  258.   {
  259.    Get_Token();
  260.    if (Token.Token_Id != COMMA_TOKEN)
  261.      {
  262.       UNGET;
  263.      }
  264.   }
  265.  
  266. static void Parse_Coeffs(order, Coeffs)
  267.   int order;
  268.   DBL *Coeffs;
  269.   {
  270.    int i;
  271.  
  272.    EXPECT
  273.      CASE (LEFT_ANGLE_TOKEN)
  274.        Coeffs[0] = Parse_Float();
  275.        for (i = 1; i < term_counts(order); i++)
  276.          {
  277.           Parse_Comma();
  278.           Coeffs[i] = Parse_Float();
  279.          }
  280.        GET (RIGHT_ANGLE_TOKEN);
  281.        EXIT
  282.      END_CASE
  283.  
  284.      OTHERWISE
  285.        Parse_Error (LEFT_ANGLE_TOKEN);
  286.      END_CASE
  287.    END_EXPECT
  288.   }
  289.  
  290. static
  291. IMAGE *Parse_Image (Legal)
  292.   int Legal;
  293.   {
  294.    IMAGE *Image;
  295.    VECTOR Local_Vector;
  296.  
  297.    Image = Create_Image ();
  298.  
  299.    if (Legal & GRAD_FILE)
  300.      {
  301.       EXPECT
  302.         CASE_VECTOR
  303.           Warn("Should use map_type keyword and/or eliminate orientation.",1.5);
  304.           Have_Vector = FALSE;
  305.           Parse_Vector_Float (&Local_Vector);
  306.           if (Have_Vector)
  307.             Image->Gradient = Local_Vector;
  308.           else
  309.             Image->Map_Type = (int)Local_Vector.x;
  310.         END_CASE
  311.  
  312.         OTHERWISE
  313.           UNGET
  314.           EXIT
  315.         END_CASE
  316.       END_EXPECT
  317.      }
  318.  
  319.    EXPECT
  320.      CASE (IFF_TOKEN)
  321.        Image->File_Type = IFF_FILE;
  322.        GET (STRING_TOKEN);
  323.        Read_Iff_Image (Image, Token.Token_String);
  324.        EXIT
  325.      END_CASE
  326.  
  327.      CASE (GIF_TOKEN)
  328.        Image->File_Type = GIF_FILE;
  329.        GET (STRING_TOKEN);
  330.        Read_Gif_Image(Image, Token.Token_String);
  331.        EXIT
  332.      END_CASE
  333.  
  334.      CASE (POT_TOKEN)
  335.        Image->File_Type = POT_FILE;
  336.        GET (STRING_TOKEN);
  337.        Read_Gif_Image(Image, Token.Token_String);
  338.        EXIT
  339.      END_CASE
  340.  
  341.      CASE (DUMP_TOKEN)
  342.        Image->File_Type = DUMP_FILE;
  343.        GET (STRING_TOKEN);
  344.        Read_Dump_Image(Image, Token.Token_String);
  345.        EXIT
  346.      END_CASE
  347.  
  348.      CASE (TGA_TOKEN)
  349.        Image->File_Type = TGA_FILE;
  350.        GET (STRING_TOKEN);
  351.        Read_Targa_Image(Image, Token.Token_String);
  352.        EXIT
  353.      END_CASE
  354.  
  355.      OTHERWISE
  356.        Parse_Error_Str ("map file spec");
  357.      END_CASE
  358.    END_EXPECT
  359.  
  360.    if (!(Image->File_Type & Legal))
  361.      Error ("File type not supported here");
  362.    return (Image);
  363.   }
  364.  
  365. static void Parse_Image_Map (Pigment)
  366.   PIGMENT *Pigment;
  367.   {
  368.    int reg;
  369.  
  370.    Pigment->Type = IMAGE_MAP_PIGMENT;
  371.  
  372.    Parse_Begin ();
  373.  
  374.    Pigment->Image = Parse_Image (IMAGE_FILE);
  375.    Pigment->Image->Use_Colour_Flag = TRUE;
  376.  
  377.    EXPECT                   /* Look for image_attribs */
  378.      CASE (ONCE_TOKEN)
  379.        Pigment->Image->Once_Flag=TRUE;
  380.      END_CASE
  381.  
  382.      CASE (INTERPOLATE_TOKEN)
  383.        Pigment->Image->Interpolation_Type = (int)Parse_Float();
  384.      END_CASE
  385.  
  386.      CASE (MAP_TYPE_TOKEN)
  387.        Pigment->Image->Map_Type = (int) Parse_Float ();
  388.      END_CASE
  389.  
  390.      CASE (USE_COLOUR_TOKEN)
  391.        Pigment->Image->Use_Colour_Flag = TRUE;
  392.      END_CASE
  393.  
  394.      CASE (USE_INDEX_TOKEN)
  395.        Pigment->Image->Use_Colour_Flag = FALSE;
  396.      END_CASE
  397.  
  398.      CASE (ALPHA_TOKEN)
  399.        Warn("Keyword ALPHA discontinued.  Use FILTER instead.",1.55);
  400.          
  401.      CASE (FILTER_TOKEN)
  402.        EXPECT
  403.          CASE (ALL_TOKEN)
  404.            {
  405.             DBL filter;
  406.             filter = Parse_Float();
  407.             for (reg = 0 ; reg < Pigment->Image->Colour_Map_Size ; reg++)
  408.               Pigment->Image->Colour_Map[reg].Filter
  409.                   = (unsigned short) (filter *255.0);
  410.            }
  411.            EXIT
  412.          END_CASE
  413.  
  414.          OTHERWISE
  415.            UNGET
  416.            reg = (int)(Parse_Float() + 0.01);
  417.            if (Pigment->Image->Colour_Map == NULL)
  418.              Error ("Can't apply FILTER to a non colour-mapped image\n");
  419.            if ((reg < 0) || (reg >= Pigment->Image->Colour_Map_Size))
  420.              Error ("FILTER colour register value out of range.\n");
  421.  
  422.            Parse_Comma();
  423.            Pigment->Image->Colour_Map[reg].Filter
  424.                   = (unsigned short) (255.0 * Parse_Float());
  425.            EXIT
  426.          END_CASE
  427.  
  428.        END_EXPECT
  429.      END_CASE
  430.  
  431.      OTHERWISE
  432.        UNGET
  433.        EXIT
  434.      END_CASE
  435.    END_EXPECT
  436.  
  437.    Parse_End ();
  438. }
  439.  
  440. static void Parse_Bump_Map (Tnormal)
  441.   TNORMAL *Tnormal;
  442.   {
  443.    Tnormal->Type = BUMP_MAP;
  444.  
  445.    Parse_Begin ();
  446.  
  447.    Tnormal->Image = Parse_Image (NORMAL_FILE);
  448.  
  449.    Tnormal->Image->Use_Colour_Flag = TRUE;
  450.  
  451.    EXPECT
  452.      CASE (ONCE_TOKEN)
  453.        Tnormal->Image->Once_Flag=TRUE;
  454.      END_CASE
  455.  
  456.      CASE (MAP_TYPE_TOKEN)
  457.        Tnormal->Image->Map_Type = (int) Parse_Float ();
  458.      END_CASE
  459.  
  460.      CASE (INTERPOLATE_TOKEN)
  461.        Tnormal->Image->Interpolation_Type = (int)Parse_Float();
  462.      END_CASE
  463.  
  464.      CASE (BUMP_SIZE_TOKEN)
  465.        Tnormal->Amount = Parse_Float ();
  466.      END_CASE
  467.  
  468.      CASE (USE_COLOUR_TOKEN)
  469.        Tnormal->Image->Use_Colour_Flag = TRUE;
  470.      END_CASE
  471.  
  472.      CASE (USE_INDEX_TOKEN)
  473.        Tnormal->Image->Use_Colour_Flag = FALSE;
  474.      END_CASE
  475.  
  476.      OTHERWISE
  477.        UNGET
  478.        EXIT
  479.      END_CASE
  480.    END_EXPECT
  481.    Parse_End ();
  482. }
  483.  
  484. static void Parse_Pigment (Pigment_Ptr)
  485.   PIGMENT **Pigment_Ptr;
  486.   {
  487.    PIGMENT *New;
  488.    VECTOR Local_Vector;
  489.  
  490.    Parse_Begin ();
  491.  
  492.    EXPECT            /* Look for [pigment_id] */
  493.      CASE (PIGMENT_ID_TOKEN)
  494.        Destroy_Pigment(*Pigment_Ptr);
  495.        *Pigment_Ptr = Copy_Pigment ((PIGMENT *) Token.Constant_Data);
  496.        EXIT
  497.      END_CASE
  498.  
  499.      OTHERWISE
  500.        UNGET
  501.        EXIT
  502.      END_CASE
  503.    END_EXPECT    /* End pigment_id */
  504.  
  505.    New = *Pigment_Ptr;
  506.  
  507.    EXPECT
  508.      CASE (AGATE_TOKEN)
  509.        New->Type = AGATE_PIGMENT;
  510.        EXIT
  511.      END_CASE
  512.  
  513.      CASE (BOZO_TOKEN)
  514.        New->Type = BOZO_PIGMENT;
  515.        EXIT
  516.      END_CASE
  517.  
  518.      CASE (GRANITE_TOKEN)
  519.        New->Type = GRANITE_PIGMENT;
  520.        EXIT
  521.      END_CASE
  522.  
  523.      CASE (LEOPARD_TOKEN)
  524.        New->Type = LEOPARD_PIGMENT;
  525.        EXIT
  526.      END_CASE
  527.  
  528.      CASE (MARBLE_TOKEN)
  529.        New->Type = MARBLE_PIGMENT;
  530.        EXIT
  531.      END_CASE
  532.  
  533.      CASE (MANDEL_TOKEN)
  534.        New->Type = MANDEL_PIGMENT;
  535.        New->Iterations = (int)Parse_Float();
  536.        EXIT
  537.      END_CASE
  538.  
  539.      CASE (ONION_TOKEN)
  540.        New->Type = ONION_PIGMENT;
  541.        EXIT
  542.      END_CASE
  543.  
  544.      CASE (PAINTED1_TOKEN)
  545.        New->Type = PAINTED1_PIGMENT;
  546.        EXIT
  547.      END_CASE
  548.  
  549.      CASE (PAINTED2_TOKEN)
  550.        New->Type = PAINTED2_PIGMENT;
  551.        EXIT
  552.      END_CASE
  553.  
  554.      CASE (PAINTED3_TOKEN)
  555.        New->Type = PAINTED2_PIGMENT;
  556.        EXIT
  557.      END_CASE
  558.  
  559.      CASE (SPOTTED_TOKEN)
  560.        New->Type = SPOTTED_PIGMENT;
  561.        EXIT
  562.      END_CASE
  563.  
  564.      CASE (WOOD_TOKEN)
  565.        New->Type = WOOD_PIGMENT;
  566.        EXIT
  567.      END_CASE
  568.  
  569.      CASE (GRADIENT_TOKEN)
  570.        New->Type = GRADIENT_PIGMENT;
  571.        Parse_Vector (&(New->Colour_Gradient));
  572.        EXIT
  573.      END_CASE
  574.  
  575.      CASE (RADIAL_TOKEN)
  576.        New->Type = RADIAL_PIGMENT;
  577.      END_CASE
  578.  
  579.      CASE (COLOUR_TOKEN)
  580.        New->Type = COLOUR_PIGMENT;
  581.        New->Colour1 = Create_Colour ();
  582.        Parse_Colour (New->Colour1);
  583.        New->Quick_Colour = *New->Colour1;
  584.        EXIT
  585.      END_CASE
  586.  
  587.      CASE5 (COLOUR_ID_TOKEN, RGB_TOKEN, RGBF_TOKEN, RED_TOKEN, BLUE_TOKEN)
  588.      CASE3 (GREEN_TOKEN, ALPHA_TOKEN, FILTER_TOKEN)
  589.        UNGET
  590.        New->Type = COLOUR_PIGMENT;
  591.        New->Colour1 = Create_Colour ();
  592.        Parse_Colour (New->Colour1);
  593.        New->Quick_Colour = *New->Colour1;
  594.        EXIT
  595.      END_CASE
  596.  
  597.      CASE (CHECKER_TOKEN)
  598.        New->Type = CHECKER_PIGMENT;
  599.        New->Colour_Map = Parse_Colour_List(2);
  600.        EXIT
  601.      END_CASE
  602.  
  603.      CASE (HEXAGON_TOKEN)
  604.        New->Type = HEXAGON_PIGMENT;
  605.        New->Colour_Map = Parse_Colour_List(3);
  606.        EXIT
  607.      END_CASE
  608.  
  609.      CASE (IMAGE_MAP_TOKEN)
  610.        Parse_Image_Map (New);
  611.        EXIT
  612.      END_CASE
  613.  
  614.      OTHERWISE
  615.        UNGET
  616.        EXIT
  617.      END_CASE
  618.    END_EXPECT     /* Concludes pigment_body */
  619.  
  620.    EXPECT         /* Look for pigment_modifier */
  621.      CASE (TURBULENCE_TOKEN)
  622.        Parse_Vector_Float(&(New->Turbulence));
  623.        if ((New->Turbulence.x !=0.0) || (New->Turbulence.y !=0.0) ||
  624.            (New->Turbulence.z !=0.0))
  625.           New->Flags |= HAS_TURB;
  626.      END_CASE
  627.  
  628.      CASE (COLOUR_MAP_TOKEN)
  629.        if (New->Type == CHECKER_PIGMENT ||
  630.            New->Type == HEXAGON_PIGMENT ||
  631.            New->Type == COLOUR_PIGMENT ||
  632.            New->Type == IMAGE_MAP_PIGMENT)
  633.          Warn ("Cannot use color map with this pigment type",1.5);
  634.        New->Colour_Map = Parse_Colour_Map ();
  635.      END_CASE
  636.  
  637.      CASE (QUICK_COLOUR_TOKEN)
  638.        Parse_Colour (&New->Quick_Colour);
  639.      END_CASE
  640.  
  641.      CASE (OCTAVES_TOKEN)
  642.        New->Octaves = (int)Parse_Float();
  643.          if(New->Octaves < 1)
  644.             New->Octaves = 1;
  645.          if(New->Octaves > 10)  /* Avoid DOMAIN errors */
  646.             New->Octaves = 10;
  647.      END_CASE
  648.  
  649.      CASE (OMEGA_TOKEN)
  650.        New->omega = Parse_Float();
  651.      END_CASE
  652.  
  653.      CASE (LAMBDA_TOKEN)
  654.        New->lambda = Parse_Float();
  655.      END_CASE
  656.  
  657.      CASE (FREQUENCY_TOKEN)
  658.        New->Frequency = Parse_Float();
  659.      END_CASE
  660.  
  661.      CASE (PHASE_TOKEN)
  662.        New->Phase = Parse_Float();
  663.      END_CASE
  664.  
  665.      CASE (AGATE_TURB_TOKEN)
  666.        if (Not_In_Default && (New->Type != AGATE_PIGMENT))
  667.       Warn("Attempt to use agate_turb on non-agate",1.9);
  668.        New->Agate_Turb_Scale = Parse_Float();
  669.      END_CASE
  670.  
  671.      CASE (TRANSLATE_TOKEN)
  672.        Parse_Vector (&Local_Vector);
  673.        Translate_Pigment (New, &Local_Vector);
  674.      END_CASE
  675.  
  676.      CASE (ROTATE_TOKEN)
  677.        Parse_Vector (&Local_Vector);
  678.        Rotate_Pigment (New, &Local_Vector);
  679.      END_CASE
  680.  
  681.      CASE (SCALE_TOKEN)
  682.        Parse_Scale_Vector (&Local_Vector);
  683.        Scale_Pigment (New, &Local_Vector);
  684.      END_CASE
  685.  
  686.      CASE (TRANSFORM_TOKEN)
  687.        GET(TRANSFORM_ID_TOKEN)
  688.        Transform_Pigment (New, (TRANSFORM *)Token.Constant_Data);
  689.      END_CASE
  690.  
  691.      OTHERWISE
  692.        UNGET
  693.        EXIT
  694.      END_CASE
  695.    END_EXPECT
  696.  
  697.    if (Not_In_Default && (New->Type == NO_PIGMENT))
  698.      Warn("Pigment type unspecified or not 1st item",1.7);
  699.  
  700.    Parse_End ();
  701.   }
  702.  
  703. static void Parse_Tnormal (Tnormal_Ptr)
  704.   TNORMAL **Tnormal_Ptr;
  705.   {
  706.    TNORMAL *New;
  707.    VECTOR Local_Vector;
  708.  
  709.    Parse_Begin ();
  710.  
  711.    EXPECT            /* Look for [tnormal_id] */
  712.      CASE (TNORMAL_ID_TOKEN)
  713.        Destroy_Tnormal(*Tnormal_Ptr);
  714.        *Tnormal_Ptr = Copy_Tnormal ((TNORMAL *) Token.Constant_Data);
  715.        EXIT
  716.      END_CASE
  717.  
  718.      OTHERWISE
  719.        UNGET
  720.        EXIT
  721.      END_CASE
  722.    END_EXPECT    /* End [tnormal_id] */
  723.  
  724.    if (*Tnormal_Ptr == NULL)
  725.      if ((Default_Texture->Tnormal) != NULL)
  726.        *Tnormal_Ptr = Copy_Tnormal ((Default_Texture->Tnormal));
  727.      else
  728.        *Tnormal_Ptr = Create_Tnormal ();
  729.  
  730.    New = *Tnormal_Ptr;
  731.  
  732.    EXPECT  /* [tnormal_body] */
  733.      CASE (BUMPS_TOKEN)
  734.        New->Type = BUMPS;
  735.        New->Amount = Parse_Float ();
  736.        EXIT
  737.      END_CASE
  738.  
  739.      CASE (BUMPY1_TOKEN)
  740.        New->Type = BUMPY1;
  741.        New->Amount = Parse_Float ();
  742.        EXIT
  743.      END_CASE
  744.  
  745.      CASE (BUMPY2_TOKEN)
  746.        New->Type = BUMPY2;
  747.        New->Amount = Parse_Float ();
  748.        EXIT
  749.      END_CASE
  750.  
  751.      CASE (BUMPY3_TOKEN)
  752.        New->Type = BUMPY3;
  753.        New->Amount = Parse_Float ();
  754.        EXIT
  755.      END_CASE
  756.  
  757.      CASE (DENTS_TOKEN)
  758.        New->Type = DENTS;
  759.        New->Amount = Parse_Float ();
  760.        EXIT
  761.      END_CASE
  762.  
  763.      CASE (RIPPLES_TOKEN)
  764.        New->Type = RIPPLES;
  765.        New->Amount = Parse_Float ();
  766.        EXIT
  767.      END_CASE
  768.  
  769.      CASE (WAVES_TOKEN)
  770.        New->Type = WAVES;
  771.        New->Amount = Parse_Float ();
  772.        EXIT
  773.      END_CASE
  774.  
  775.      CASE (WRINKLES_TOKEN)
  776.        New->Type = WRINKLES;
  777.        New->Amount = Parse_Float ();
  778.        EXIT
  779.      END_CASE
  780.  
  781.      CASE (BUMP_MAP_TOKEN)
  782.        Parse_Bump_Map (New);
  783.        EXIT
  784.      END_CASE
  785.  
  786.      OTHERWISE
  787.        if (Not_In_Default && (New->Type == NO_NORMAL))
  788.          Parse_Error_Str("normal body");
  789.        UNGET
  790.        EXIT
  791.      END_CASE
  792.    END_EXPECT    /* End of tnormal_body */
  793.  
  794.    EXPECT        /* Look for tnormal_mods */
  795.  
  796.      CASE (TURBULENCE_TOKEN)
  797.        Parse_Vector_Float(&(New->Turbulence));
  798.        if ((New->Turbulence.x !=0.0) || (New->Turbulence.y !=0.0) ||
  799.            (New->Turbulence.z !=0.0))
  800.           New->Flags |= HAS_TURB;
  801.      END_CASE
  802.  
  803.      CASE (OCTAVES_TOKEN)
  804.        New->Octaves = (int)Parse_Float();
  805.      END_CASE
  806.  
  807.      CASE (OMEGA_TOKEN)
  808.        New->omega = Parse_Float();
  809.      END_CASE
  810.  
  811.      CASE (LAMBDA_TOKEN)
  812.        New->lambda = Parse_Float();
  813.      END_CASE
  814.  
  815.      CASE (FREQUENCY_TOKEN)
  816.        if (!(New->Type == RIPPLES || New->Type == WAVES))
  817.          if (Language_Version >= 1.5)
  818.            Warn ("Cannot use frequency with this normal",1.5);
  819.        New->Frequency = Parse_Float();
  820.      END_CASE
  821.  
  822.      CASE (PHASE_TOKEN)
  823.        if (!(New->Type == RIPPLES || New->Type == WAVES))
  824.          if (Language_Version >= 1.5)
  825.             Warn ("Cannot use phase with this normal",1.5);
  826.        New->Phase = Parse_Float();
  827.      END_CASE
  828.  
  829.      CASE (TRANSLATE_TOKEN)
  830.        Parse_Vector (&Local_Vector);
  831.        Translate_Tnormal (New, &Local_Vector);
  832.      END_CASE
  833.  
  834.      CASE (ROTATE_TOKEN)
  835.        Parse_Vector (&Local_Vector);
  836.        Rotate_Tnormal (New, &Local_Vector);
  837.      END_CASE
  838.  
  839.      CASE (SCALE_TOKEN)
  840.        Parse_Scale_Vector (&Local_Vector);
  841.        Scale_Tnormal (New, &Local_Vector);
  842.      END_CASE
  843.  
  844.      CASE (TRANSFORM_TOKEN)
  845.        GET(TRANSFORM_ID_TOKEN)
  846.        Transform_Tnormal (New, (TRANSFORM *)Token.Constant_Data);
  847.      END_CASE
  848.  
  849.      OTHERWISE
  850.        UNGET
  851.        EXIT
  852.      END_CASE
  853.    END_EXPECT    /* End of tnormal_mods */
  854.  
  855.    Parse_End ();
  856.   }
  857.  
  858. static void Parse_Finish (Finish_Ptr)
  859.   FINISH **Finish_Ptr;
  860.   {
  861.    FINISH *New;
  862.  
  863.    Parse_Begin ();
  864.  
  865.    EXPECT        /* Look for zero or one finish_id */
  866.      CASE (FINISH_ID_TOKEN)
  867.        Destroy_Finish(*Finish_Ptr);
  868.        *Finish_Ptr = Copy_Finish ((FINISH *) Token.Constant_Data);
  869.        EXIT
  870.      END_CASE
  871.  
  872.      OTHERWISE
  873.        UNGET
  874.        EXIT
  875.      END_CASE
  876.    END_EXPECT    /* End finish_id */
  877.  
  878.    New = *Finish_Ptr;
  879.  
  880.    EXPECT        /* Look for zero or more finish_body */
  881.      CASE (AMBIENT_TOKEN)
  882.        New->Ambient = Parse_Float ();
  883.      END_CASE
  884.  
  885.      CASE (BRILLIANCE_TOKEN)
  886.        New->Brilliance = Parse_Float ();
  887.      END_CASE
  888.  
  889.      CASE (DIFFUSE_TOKEN)
  890.        New->Diffuse = Parse_Float ();
  891.      END_CASE
  892.  
  893.      CASE (REFLECTION_TOKEN)
  894.        New->Reflection = Parse_Float ();
  895.      END_CASE
  896.  
  897.      CASE (REFRACTION_TOKEN)
  898.        New->Refraction = Parse_Float ();
  899.      END_CASE
  900.  
  901.      CASE (IOR_TOKEN)
  902.        New->Index_Of_Refraction = Parse_Float ();
  903.      END_CASE
  904.  
  905.      CASE (PHONG_TOKEN)
  906.        New->Phong = Parse_Float ();
  907.      END_CASE
  908.  
  909.      CASE (PHONG_SIZE_TOKEN)
  910.        New->Phong_Size = Parse_Float ();
  911. /*     if (New->Phong_Size < 1.0)
  912.            New->Phong_Size = 1.0;
  913.        if (New->Phong_Size > 100)
  914.            New->Phong_Size = 100; */
  915.      END_CASE
  916.  
  917.      CASE (SPECULAR_TOKEN)
  918.        New->Specular = Parse_Float ();
  919.      END_CASE
  920.  
  921.      CASE (ROUGHNESS_TOKEN)
  922.        New->Roughness = Parse_Float ();
  923. /*     if (New->Roughness > 1.0)
  924.            New->Roughness = 1.0;
  925.        if (New->Roughness < 0.001)
  926.            New->Roughness = 0.001;  */
  927.        New->Roughness = 1.0/New->Roughness; /* CEY 12/92 */
  928.      END_CASE
  929.  
  930.      CASE (METALLIC_TOKEN)
  931.        New->Metallic_Flag = TRUE;
  932.      END_CASE
  933.  
  934.      CASE (CRAND_TOKEN)
  935.        New->Crand = Parse_Float();
  936.      END_CASE
  937.  
  938.      OTHERWISE
  939.        UNGET
  940.        EXIT
  941.      END_CASE
  942.    END_EXPECT    /* End of finish_body */
  943.  
  944.    EXPECT        /* Look for finish_mods */
  945.  
  946. /*   CASE none implemented
  947.      END_CASE     */
  948.  
  949.      OTHERWISE
  950.        UNGET
  951.        EXIT
  952.      END_CASE
  953.    END_EXPECT    /* End of finish_mods */
  954.  
  955.    Parse_End ();
  956.   }
  957.  
  958. #define ADD_TNORMAL if (Tnormal == NULL) {if ((Default_Texture->Tnormal) != NULL) \
  959.  Tnormal = Copy_Tnormal ((Default_Texture->Tnormal)); else Tnormal = Create_Tnormal ();\
  960.  Texture->Tnormal=Tnormal;};
  961.  
  962. static
  963. TEXTURE *Parse_Texture ()
  964.   {
  965.    VECTOR Local_Vector;
  966.    TEXTURE *Texture, *Local_Texture;
  967.    PIGMENT *Pigment;
  968.    TNORMAL *Tnormal;
  969.    FINISH *Finish;
  970.  
  971.    Parse_Begin ();
  972.  
  973.    EXPECT                      /* Look for texture_body */
  974.      CASE (TILES_TOKEN)
  975.        Parse_Begin ();
  976.  
  977.        Texture = (TEXTURE *)Create_Tiles_Texture ();
  978.  
  979.        EXPECT
  980.          CASE (TEXTURE_TOKEN)
  981.            Local_Texture = Parse_Texture ();
  982.            Link_Textures(&(((TILES *)Texture)->Tile1),Local_Texture);
  983.          END_CASE
  984.  
  985.          OTHERWISE
  986.            UNGET
  987.            EXIT
  988.          END_CASE
  989.        END_EXPECT
  990.  
  991.        GET (TILE2_TOKEN);
  992.  
  993.        EXPECT
  994.          CASE (TEXTURE_TOKEN)
  995.            Local_Texture = Parse_Texture ();
  996.            Link_Textures(&(((TILES *)Texture)->Tile2),Local_Texture);
  997.          END_CASE
  998.  
  999.          OTHERWISE
  1000.            UNGET
  1001.            EXIT
  1002.          END_CASE
  1003.        END_EXPECT
  1004.        Parse_End ();
  1005.        EXIT
  1006.      END_CASE
  1007.  
  1008.      CASE (MATERIAL_MAP_TOKEN)
  1009.        Parse_Begin ();
  1010.  
  1011.        Texture = (TEXTURE *)Create_Material_Texture ();
  1012.  
  1013.        ((MATERIAL *)Texture)->Image = Parse_Image(MATERIAL_FILE);
  1014.        ((MATERIAL *)Texture)->Image->Use_Colour_Flag = FALSE;
  1015.  
  1016.        EXPECT
  1017.          CASE (ONCE_TOKEN)
  1018.            ((MATERIAL *)Texture)->Image->Once_Flag=TRUE;
  1019.          END_CASE
  1020.  
  1021.          CASE (INTERPOLATE_TOKEN)
  1022.            ((MATERIAL *)Texture)->Image->Interpolation_Type=(int)Parse_Float();
  1023.          END_CASE
  1024.  
  1025.          CASE (MAP_TYPE_TOKEN)
  1026.            ((MATERIAL *)Texture)->Image->Map_Type = (int) Parse_Float ();
  1027.          END_CASE
  1028.  
  1029.          OTHERWISE
  1030.            UNGET
  1031.            EXIT
  1032.          END_CASE
  1033.        END_EXPECT
  1034.  
  1035.        GET (TEXTURE_TOKEN)                /* First material */
  1036.        ((MATERIAL *)Texture)->Materials = Local_Texture = Parse_Texture ();
  1037.        ((MATERIAL *)Texture)->Num_Of_Mats++;
  1038.  
  1039.        EXPECT                             /* Subsequent materials */
  1040.          CASE (TEXTURE_TOKEN)
  1041.            Local_Texture->Next_Material = Parse_Texture ();
  1042.            Local_Texture = Local_Texture->Next_Material;
  1043.            ((MATERIAL *)Texture)->Num_Of_Mats++;
  1044.          END_CASE
  1045.  
  1046.          OTHERWISE
  1047.            UNGET
  1048.            EXIT
  1049.          END_CASE
  1050.        END_EXPECT
  1051.        Parse_End ();
  1052.        EXIT
  1053.      END_CASE
  1054.      
  1055.      CASE (TEXTURE_ID_TOKEN)
  1056.        Texture = Copy_Textures((TEXTURE *) Token.Constant_Data);
  1057.        EXIT
  1058.      END_CASE
  1059.  
  1060.      OTHERWISE
  1061.        UNGET
  1062.        Texture = Copy_Textures (Default_Texture);
  1063.        EXIT
  1064.      END_CASE
  1065.    END_EXPECT
  1066.    
  1067.    /* Look for [pnf_texture] */
  1068.    if (Texture->Type == PNF_TEXTURE)
  1069.      {
  1070.        EXPECT   /* Look for [pnf_ids] */
  1071.          CASE (PIGMENT_ID_TOKEN)
  1072.            Destroy_Pigment(Texture->Pigment);
  1073.            Texture->Pigment = Copy_Pigment ((PIGMENT *) Token.Constant_Data);
  1074.          END_CASE
  1075.  
  1076.          CASE (TNORMAL_ID_TOKEN)
  1077.            Destroy_Tnormal(Texture->Tnormal);
  1078.            Texture->Tnormal = Copy_Tnormal ((TNORMAL *) Token.Constant_Data);
  1079.          END_CASE
  1080.  
  1081.          CASE (FINISH_ID_TOKEN)
  1082.            Destroy_Finish(Texture->Finish);
  1083.            Texture->Finish = Copy_Finish ((FINISH *) Token.Constant_Data);
  1084.          END_CASE
  1085.  
  1086.          OTHERWISE
  1087.            UNGET
  1088.            EXIT
  1089.          END_CASE
  1090.        END_EXPECT
  1091.  
  1092.        Pigment = Texture->Pigment;
  1093.        Tnormal = Texture->Tnormal;
  1094.        Finish  = Texture->Finish;
  1095.  
  1096.        EXPECT
  1097.          CASE (PIGMENT_TOKEN)
  1098.            Parse_Pigment ( &(Texture->Pigment) );
  1099.          END_CASE
  1100.  
  1101.          CASE (TNORMAL_TOKEN)
  1102.            Parse_Tnormal ( &(Texture->Tnormal) );
  1103.          END_CASE
  1104.  
  1105.          CASE (FINISH_TOKEN)
  1106.            Parse_Finish ( &(Texture->Finish) );
  1107.          END_CASE
  1108.  
  1109. /***********************************************************************
  1110.  PIGMENT STUFF OUTSIDE PIGMENT{}
  1111. ***********************************************************************/
  1112.          CASE (AGATE_TOKEN)
  1113.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1114.            Pigment->Type = AGATE_PIGMENT;
  1115.          END_CASE
  1116.  
  1117.          CASE (BOZO_TOKEN)
  1118.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1119.            Pigment->Type = BOZO_PIGMENT;
  1120.          END_CASE
  1121.  
  1122.          CASE (GRANITE_TOKEN)
  1123.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1124.            Pigment->Type = GRANITE_PIGMENT;
  1125.          END_CASE
  1126.  
  1127.          CASE (LEOPARD_TOKEN)
  1128.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1129.            Pigment->Type = LEOPARD_PIGMENT;
  1130.          END_CASE
  1131.  
  1132.          CASE (MARBLE_TOKEN)
  1133.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1134.            Pigment->Type = MARBLE_PIGMENT;
  1135.          END_CASE
  1136.  
  1137.          CASE (MANDEL_TOKEN)
  1138.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1139.            Pigment->Type = MANDEL_PIGMENT;
  1140.            Pigment->Iterations = (int)Parse_Float();
  1141.          END_CASE
  1142.  
  1143.          CASE (ONION_TOKEN)
  1144.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1145.            Pigment->Type = ONION_PIGMENT;
  1146.          END_CASE
  1147.  
  1148.          CASE (PAINTED1_TOKEN)
  1149.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1150.            Pigment->Type = PAINTED1_PIGMENT;
  1151.          END_CASE
  1152.  
  1153.          CASE (PAINTED2_TOKEN)
  1154.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1155.            Pigment->Type = PAINTED2_PIGMENT;
  1156.          END_CASE
  1157.  
  1158.          CASE (PAINTED3_TOKEN)
  1159.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1160.            Pigment->Type = PAINTED2_PIGMENT;
  1161.          END_CASE
  1162.  
  1163.          CASE (SPOTTED_TOKEN)
  1164.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1165.            Pigment->Type = SPOTTED_PIGMENT;
  1166.          END_CASE
  1167.  
  1168.          CASE (WOOD_TOKEN)
  1169.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1170.            Pigment->Type = WOOD_PIGMENT;
  1171.          END_CASE
  1172.  
  1173.          CASE (GRADIENT_TOKEN)
  1174.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1175.            Pigment->Type = GRADIENT_PIGMENT;
  1176.            Parse_Vector (&(Pigment->Colour_Gradient));
  1177.          END_CASE
  1178.  
  1179.          CASE (COLOUR_TOKEN)
  1180.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1181.            Pigment->Type = COLOUR_PIGMENT;
  1182.            Pigment->Colour1 = Create_Colour ();
  1183.            Parse_Colour (Pigment->Colour1);
  1184.            Pigment->Quick_Colour = *Pigment->Colour1;
  1185.          END_CASE
  1186.  
  1187.          CASE5 (COLOUR_ID_TOKEN, RGB_TOKEN, RGBF_TOKEN, RED_TOKEN, BLUE_TOKEN)
  1188.          CASE3 (GREEN_TOKEN, ALPHA_TOKEN, FILTER_TOKEN)
  1189.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1190.            UNGET
  1191.            Pigment->Type = COLOUR_PIGMENT;
  1192.            Pigment->Colour1 = Create_Colour ();
  1193.            Parse_Colour (Pigment->Colour1);
  1194.            Pigment->Quick_Colour = *Pigment->Colour1;
  1195.          END_CASE
  1196.  
  1197.          CASE (CHECKER_TOKEN)
  1198.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1199.            Pigment->Type = CHECKER_PIGMENT;
  1200.            Pigment->Colour_Map = Parse_Colour_List(2);
  1201.          END_CASE
  1202.  
  1203.          CASE (HEXAGON_TOKEN)
  1204.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1205.            Pigment->Type = HEXAGON_PIGMENT;
  1206.            Pigment->Colour_Map = Parse_Colour_List(3);
  1207.          END_CASE
  1208.  
  1209.          CASE (IMAGE_MAP_TOKEN)
  1210.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1211.            Parse_Image_Map (Pigment);
  1212.          END_CASE
  1213.  
  1214.          CASE (TURBULENCE_TOKEN)
  1215.            Parse_Vector_Float(&(Pigment->Turbulence));
  1216.            if ((Pigment->Turbulence.x !=0.0) ||
  1217.                (Pigment->Turbulence.y !=0.0) ||
  1218.                (Pigment->Turbulence.z !=0.0))
  1219.              Pigment->Flags |= HAS_TURB;
  1220.          END_CASE
  1221.  
  1222.          CASE (COLOUR_MAP_TOKEN)
  1223.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);
  1224.            if (Pigment->Type == CHECKER_PIGMENT ||
  1225.                Pigment->Type == HEXAGON_PIGMENT ||
  1226.                Pigment->Type == COLOUR_PIGMENT ||
  1227.                Pigment->Type == IMAGE_MAP_PIGMENT)
  1228.              Warn ("Cannot use color map with this pigment type",1.5);
  1229.            Pigment->Colour_Map = Parse_Colour_Map ();
  1230.          END_CASE
  1231.  
  1232.          CASE (QUICK_COLOUR_TOKEN)
  1233.            Warn_State(Token.Token_Id, PIGMENT_TOKEN);           
  1234.            Parse_Colour (&Pigment->Quick_Colour);
  1235.          END_CASE
  1236.  
  1237.          CASE (OCTAVES_TOKEN)
  1238.            Pigment->Octaves = (int)Parse_Float();
  1239.              if(Pigment->Octaves < 1)
  1240.                 Pigment->Octaves = 1;
  1241.              if(Pigment->Octaves > 10)  /* Avoid DOMAIN errors */
  1242.                 Pigment->Octaves = 10;
  1243.          END_CASE
  1244.  
  1245.          CASE (OMEGA_TOKEN)
  1246.            Pigment->omega = Parse_Float();
  1247.          END_CASE
  1248.  
  1249.          CASE (LAMBDA_TOKEN)
  1250.            Pigment->lambda = Parse_Float();
  1251.          END_CASE
  1252.  
  1253. /***********************************************************************
  1254. TNORMAL STUFF OUTSIDE NORMAL{}
  1255. ***********************************************************************/
  1256.          CASE (BUMPS_TOKEN)
  1257.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1258.            ADD_TNORMAL
  1259.            Tnormal->Type = BUMPS;
  1260.            Tnormal->Amount = Parse_Float ();
  1261.          END_CASE
  1262.  
  1263.          CASE (BUMPY1_TOKEN)
  1264.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1265.            ADD_TNORMAL
  1266.            Tnormal->Type = BUMPY1;
  1267.            Tnormal->Amount = Parse_Float ();
  1268.          END_CASE
  1269.  
  1270.          CASE (BUMPY2_TOKEN)
  1271.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1272.            ADD_TNORMAL
  1273.            Tnormal->Type = BUMPY2;
  1274.            Tnormal->Amount = Parse_Float ();
  1275.          END_CASE
  1276.  
  1277.          CASE (BUMPY3_TOKEN)
  1278.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1279.            ADD_TNORMAL
  1280.            Tnormal->Type = BUMPY3;
  1281.            Tnormal->Amount = Parse_Float ();
  1282.          END_CASE
  1283.  
  1284.          CASE (DENTS_TOKEN)
  1285.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1286.            ADD_TNORMAL
  1287.            Tnormal->Type = DENTS;
  1288.            Tnormal->Amount = Parse_Float ();
  1289.          END_CASE
  1290.  
  1291.          CASE (RIPPLES_TOKEN)
  1292.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1293.            ADD_TNORMAL
  1294.            Tnormal->Type = RIPPLES;
  1295.            Tnormal->Amount = Parse_Float ();
  1296.          END_CASE
  1297.  
  1298.          CASE (WAVES_TOKEN)
  1299.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1300.            ADD_TNORMAL
  1301.            Tnormal->Type = WAVES;
  1302.            Tnormal->Amount = Parse_Float ();
  1303.          END_CASE
  1304.  
  1305.          CASE (WRINKLES_TOKEN)
  1306.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1307.            ADD_TNORMAL
  1308.            Tnormal->Type = WRINKLES;
  1309.            Tnormal->Amount = Parse_Float ();
  1310.          END_CASE
  1311.  
  1312.          CASE (BUMP_MAP_TOKEN)
  1313.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1314.            ADD_TNORMAL
  1315.            Parse_Bump_Map (Tnormal);
  1316.          END_CASE
  1317.  
  1318.          CASE (FREQUENCY_TOKEN)
  1319.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1320.            ADD_TNORMAL
  1321.            if (!(Tnormal->Type == RIPPLES || Tnormal->Type == WAVES))
  1322.              if (Language_Version >= 1.5)
  1323.                Warn ("Cannot use frequency with this normal",1.5);
  1324.            Tnormal->Frequency = Parse_Float();
  1325.          END_CASE
  1326.  
  1327.          CASE (PHASE_TOKEN)
  1328.            Warn_State(Token.Token_Id, TNORMAL_TOKEN);           
  1329.            ADD_TNORMAL
  1330.            if (!(Tnormal->Type == RIPPLES || Tnormal->Type == WAVES))
  1331.              if (Language_Version >= 1.5)
  1332.                Warn ("Cannot use phase with this normal",1.5);
  1333.            Tnormal->Phase = Parse_Float();
  1334.          END_CASE
  1335.  
  1336.  
  1337. /***********************************************************************
  1338. FINISH STUFF OUTSIDE FINISH{}
  1339. ***********************************************************************/
  1340.          CASE (AMBIENT_TOKEN)
  1341.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1342.            Finish->Ambient = Parse_Float ();
  1343.          END_CASE
  1344.  
  1345.          CASE (BRILLIANCE_TOKEN)
  1346.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1347.            Finish->Brilliance = Parse_Float ();
  1348.          END_CASE
  1349.  
  1350.          CASE (DIFFUSE_TOKEN)
  1351.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1352.            Finish->Diffuse = Parse_Float ();
  1353.          END_CASE
  1354.  
  1355.          CASE (REFLECTION_TOKEN)
  1356.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1357.            Finish->Reflection = Parse_Float ();
  1358.          END_CASE
  1359.  
  1360.          CASE (REFRACTION_TOKEN)
  1361.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1362.            Finish->Refraction = Parse_Float ();
  1363.          END_CASE
  1364.  
  1365.          CASE (IOR_TOKEN)
  1366.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1367.        Finish->Index_Of_Refraction = Parse_Float ();
  1368.          END_CASE
  1369.  
  1370.          CASE (PHONG_TOKEN)
  1371.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1372.            Finish->Phong = Parse_Float ();
  1373.          END_CASE
  1374.  
  1375.          CASE (PHONG_SIZE_TOKEN)
  1376.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1377.            Finish->Phong_Size = Parse_Float ();
  1378.     /*     if (Finish->Phong_Size < 1.0)
  1379.                Finish->Phong_Size = 1.0;
  1380.            if (Finish->Phong_Size > 100)
  1381.                Finish->Phong_Size = 100; */
  1382.          END_CASE
  1383.  
  1384.          CASE (SPECULAR_TOKEN)
  1385.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1386.            Finish->Specular = Parse_Float ();
  1387.          END_CASE
  1388.  
  1389.          CASE (ROUGHNESS_TOKEN)
  1390.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1391.            Finish->Roughness = Parse_Float ();
  1392.     /*     if (Finish->Roughness > 1.0)
  1393.                Finish->Roughness = 1.0;
  1394.            if (Finish->Roughness < 0.001)
  1395.                Finish->Roughness = 0.001;  */
  1396.            Finish->Roughness = 1.0/Finish->Roughness; /* CEY 12/92 */
  1397.          END_CASE
  1398.  
  1399.          CASE (METALLIC_TOKEN)
  1400.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1401.            Finish->Metallic_Flag = TRUE;
  1402.      END_CASE
  1403.  
  1404.          CASE (CRAND_TOKEN)
  1405.            Warn_State(Token.Token_Id, FINISH_TOKEN);           
  1406.            Finish->Crand = Parse_Float();
  1407.          END_CASE
  1408.  
  1409.          CASE_FLOAT
  1410.            Finish->Crand = Parse_Float();
  1411.            Warn("Should use crand keyword in finish statement.",1.5);           
  1412.          END_CASE
  1413.  
  1414.          CASE (TRANSLATE_TOKEN)
  1415.            Parse_Vector (&Local_Vector);
  1416.            Translate_Textures (Texture, &Local_Vector);
  1417.          END_CASE
  1418.  
  1419.          CASE (ROTATE_TOKEN)
  1420.            Parse_Vector (&Local_Vector);
  1421.            Rotate_Textures (Texture, &Local_Vector);
  1422.          END_CASE
  1423.  
  1424.          CASE (SCALE_TOKEN)
  1425.            Parse_Scale_Vector (&Local_Vector);
  1426.            Scale_Textures (Texture, &Local_Vector);
  1427.          END_CASE
  1428.  
  1429.          CASE (TRANSFORM_TOKEN)
  1430.            GET(TRANSFORM_ID_TOKEN)
  1431.            Transform_Textures (Texture, (TRANSFORM *)Token.Constant_Data);
  1432.          END_CASE
  1433.  
  1434.          CASE (TEXTURE_ID_TOKEN)
  1435.            Warn("Texture identifier overwriting previous values.",0);
  1436.            Destroy_Textures(Texture);
  1437.        Texture = Copy_Textures((TEXTURE *) Token.Constant_Data);
  1438.            Pigment = Texture->Pigment;
  1439.            Tnormal = Texture->Tnormal;
  1440.            Finish  = Texture->Finish;
  1441.          END_CASE
  1442.  
  1443.          OTHERWISE
  1444.            UNGET
  1445.            EXIT
  1446.          END_CASE
  1447. /***********************************************************************/
  1448.  
  1449.        END_EXPECT
  1450.  
  1451.        if (Not_In_Default && (Texture->Pigment->Type == NO_PIGMENT) &&
  1452.            !(Language_Version < 1.5))
  1453.          Parse_Error(PIGMENT_ID_TOKEN);
  1454.  
  1455.      }
  1456.  
  1457.    EXPECT            /* Look for texture_mods */
  1458.      CASE (TRANSLATE_TOKEN)
  1459.        Parse_Vector (&Local_Vector);
  1460.        Translate_Textures (Texture, &Local_Vector);
  1461.      END_CASE
  1462.  
  1463.      CASE (ROTATE_TOKEN)
  1464.        Parse_Vector (&Local_Vector);
  1465.        Rotate_Textures (Texture, &Local_Vector);
  1466.      END_CASE
  1467.  
  1468.      CASE (SCALE_TOKEN)
  1469.        Parse_Scale_Vector (&Local_Vector);
  1470.        Scale_Textures (Texture, &Local_Vector);
  1471.      END_CASE
  1472.  
  1473.      CASE (TRANSFORM_TOKEN)
  1474.        GET(TRANSFORM_ID_TOKEN)
  1475.        Transform_Textures (Texture, (TRANSFORM *)Token.Constant_Data);
  1476.      END_CASE
  1477.  
  1478.      OTHERWISE
  1479.        UNGET
  1480.        EXIT
  1481.      END_CASE
  1482.    END_EXPECT        /* End of texture */
  1483.  
  1484.    Parse_End ();
  1485.    return (Texture);
  1486.   }
  1487.  
  1488. static
  1489. OBJECT *Parse_Bound_Clip ()
  1490.   {
  1491.    VECTOR Local_Vector;
  1492.    OBJECT *First, *Current, *Prev;
  1493.  
  1494.    First = Prev = NULL;
  1495.  
  1496.    while ((Current = Parse_Object ()) != NULL)
  1497.      {
  1498.       if (Current->Type & (TEXTURED_OBJECT+PATCH_OBJECT))
  1499.         Error ("Illegal texture or patch in clip or bound");
  1500.       if (First == NULL)
  1501.         First = Current;
  1502.       if (Prev != NULL)
  1503.         Prev->Sibling = Current;
  1504.       Prev = Current;
  1505.      }
  1506.  
  1507.    EXPECT
  1508.      CASE (TRANSLATE_TOKEN)
  1509.        Parse_Vector (&Local_Vector);
  1510.        for (Current = First;
  1511.             Current != NULL;
  1512.             Current = Current->Sibling)
  1513.          Translate_Object (Current, &Local_Vector);
  1514.      END_CASE
  1515.  
  1516.      CASE (ROTATE_TOKEN)
  1517.        Parse_Vector (&Local_Vector);
  1518.        for (Current = First;
  1519.             Current != NULL;
  1520.             Current = Current->Sibling)
  1521.          Rotate_Object (Current, &Local_Vector);
  1522.      END_CASE
  1523.  
  1524.      CASE (SCALE_TOKEN)
  1525.        Parse_Scale_Vector (&Local_Vector);
  1526.        for (Current = First;
  1527.             Current != NULL;
  1528.             Current = Current->Sibling)
  1529.          Scale_Object (Current, &Local_Vector);
  1530.      END_CASE
  1531.  
  1532.      CASE (TRANSFORM_TOKEN)
  1533.        GET(TRANSFORM_ID_TOKEN)
  1534.        for (Current = First;
  1535.             Current != NULL;
  1536.             Current = Current->Sibling)
  1537.        Transform_Object (Current, (TRANSFORM *)Token.Constant_Data);
  1538.      END_CASE
  1539.  
  1540.      OTHERWISE
  1541.        UNGET
  1542.        EXIT
  1543.      END_CASE
  1544.    END_EXPECT
  1545.  
  1546.    return (First);
  1547.   }
  1548.  
  1549. static void Parse_Object_Mods (Object)
  1550.   OBJECT *Object;
  1551.   {
  1552.    VECTOR Local_Vector;
  1553.    TEXTURE *Local_Texture;
  1554.    OBJECT *Temp1_Object;
  1555.    OBJECT *Temp2_Object;
  1556.    COLOUR Local_Colour;
  1557.    DBL Temp_Water_Level;
  1558.  
  1559.    EXPECT
  1560.      CASE (COLOUR_TOKEN)
  1561.        Parse_Colour (&Local_Colour);
  1562.        if (Language_Version < 1.5)
  1563.          if (Object->Texture != NULL) 
  1564.            if (Object->Texture->Type == PNF_TEXTURE)
  1565.              {
  1566.               Object->Texture->Pigment->Quick_Colour = Local_Colour;
  1567.               break;  /* acts like END_CASE */
  1568.              }
  1569.        Warn("Quick color belongs in texture.  Color ignored.",0.0);
  1570.      END_CASE
  1571.  
  1572.      CASE (TRANSLATE_TOKEN)
  1573.        Parse_Vector (&Local_Vector);
  1574.        Translate_Object (Object, &Local_Vector);
  1575.      END_CASE
  1576.  
  1577.      CASE (ROTATE_TOKEN)
  1578.        Parse_Vector (&Local_Vector);
  1579.        Rotate_Object (Object, &Local_Vector);
  1580.      END_CASE
  1581.  
  1582.      CASE (SCALE_TOKEN)
  1583.        Parse_Scale_Vector (&Local_Vector);
  1584.        Scale_Object (Object, &Local_Vector);
  1585.      END_CASE
  1586.  
  1587.      CASE (TRANSFORM_TOKEN)
  1588.        GET(TRANSFORM_ID_TOKEN)
  1589.        Transform_Object (Object, (TRANSFORM *)Token.Constant_Data);
  1590.      END_CASE
  1591.  
  1592.      CASE (BOUNDED_BY_TOKEN)
  1593.        Parse_Begin ();
  1594.        if (Object->Bound != NULL)
  1595.          if (Object->Clip == Object->Bound)
  1596.            Error ("Cannot add bounds after linking bounds and clips");
  1597.  
  1598.        EXPECT
  1599.          CASE (CLIPPED_BY_TOKEN)
  1600.            if (Object->Bound != NULL)
  1601.              Error ("Cannot link clips with previous bounds");
  1602.            Object->Bound = Object->Clip;
  1603.            EXIT
  1604.          END_CASE
  1605.  
  1606.          OTHERWISE
  1607.            UNGET
  1608.            Temp1_Object = Temp2_Object = Parse_Bound_Clip ();
  1609.            while (Temp2_Object->Sibling != NULL)
  1610.              Temp2_Object = Temp2_Object->Sibling;
  1611.            Temp2_Object->Sibling = Object->Bound;
  1612.        Object->Bound = Temp1_Object;
  1613.            EXIT
  1614.          END_CASE
  1615.        END_EXPECT
  1616.        
  1617.        Parse_End ();
  1618.      END_CASE
  1619.  
  1620.      CASE (CLIPPED_BY_TOKEN)
  1621.        Parse_Begin ();
  1622.        if (Object->Clip != NULL)
  1623.          if (Object->Clip == Object->Bound)
  1624.            Error ("Cannot add clips after linking bounds and clips");
  1625.  
  1626.        EXPECT
  1627.          CASE (BOUNDED_BY_TOKEN)
  1628.            if (Object->Clip != NULL)
  1629.              Error ("Cannot link bounds with previous clips");
  1630.            Object->Clip = Object->Bound;
  1631.            EXIT
  1632.          END_CASE
  1633.  
  1634.          OTHERWISE
  1635.            UNGET
  1636.            Temp1_Object = Temp2_Object = Parse_Bound_Clip ();
  1637.            while (Temp2_Object->Sibling != NULL)
  1638.              Temp2_Object = Temp2_Object->Sibling;
  1639.            Temp2_Object->Sibling = Object->Clip;
  1640.            Object->Clip = Temp1_Object;
  1641. #ifdef DB_CODE
  1642.        /* necessary for bounding of quadrics. */
  1643.        if (Object->Methods == &Quadric_Methods)
  1644.          Compute_Quadric_BBox((QUADRIC *)Object);
  1645. #endif
  1646.        EXIT
  1647.          END_CASE
  1648.        END_EXPECT
  1649.  
  1650.        Parse_End ();
  1651.      END_CASE
  1652.  
  1653.      CASE (TEXTURE_TOKEN)
  1654.        Object->Type |= TEXTURED_OBJECT;
  1655.        Local_Texture = Parse_Texture ();
  1656.        Link_Textures(&(Object->Texture), Local_Texture);
  1657.      END_CASE
  1658.  
  1659.      CASE3 (PIGMENT_TOKEN, TNORMAL_TOKEN, FINISH_TOKEN)
  1660.        Object->Type |= TEXTURED_OBJECT;
  1661.        if (Object->Texture == NULL)
  1662.          Object->Texture = Copy_Textures(Default_Texture);
  1663.        else
  1664.          if (Object->Texture->Type != PNF_TEXTURE)
  1665.            Link_Textures(&(Object->Texture), Copy_Textures(Default_Texture));
  1666.        UNGET
  1667.        EXPECT
  1668.          CASE (PIGMENT_TOKEN)
  1669.            Parse_Pigment ( &(Object->Texture->Pigment) );
  1670.          END_CASE
  1671.  
  1672.          CASE (TNORMAL_TOKEN)
  1673.            Parse_Tnormal ( &(Object->Texture->Tnormal) );
  1674.          END_CASE
  1675.  
  1676.          CASE (FINISH_TOKEN)
  1677.            Parse_Finish ( &(Object->Texture->Finish) );
  1678.          END_CASE
  1679.  
  1680.          OTHERWISE
  1681.            UNGET
  1682.            EXIT
  1683.      END_CASE
  1684.        END_EXPECT
  1685.      END_CASE
  1686.  
  1687.      CASE (INVERSE_TOKEN)
  1688.        if (Object->Type & PATCH_OBJECT)
  1689.          Warn ("Cannot invert a patch object",0.0);
  1690.        Invert_Object (Object);
  1691.      END_CASE
  1692.  
  1693.      CASE (STURM_TOKEN)
  1694.        if (!(Object->Type & STURM_OK_OBJECT))
  1695.          Error ("Cannot use STRUM here");
  1696.        ((POLY *) Object)->Sturm_Flag = TRUE;
  1697.      END_CASE
  1698.  
  1699.      CASE (WATER_LEVEL_TOKEN)
  1700.        if (!(Object->Type & WATER_LEVEL_OK_OBJECT))
  1701.          Error ("Cannot use WATER_LEVEL here");
  1702.        Temp_Water_Level = Parse_Float();
  1703.        if (Language_Version < 2.0)
  1704.          Temp_Water_Level /=256.0;
  1705.        ((HEIGHT_FIELD *) Object)->bounding_box->bounds[0].y = 65536.0 * Temp_Water_Level;
  1706.      END_CASE
  1707.  
  1708.      CASE (SMOOTH_TOKEN)
  1709.        if (!(Object->Type & SMOOTH_OK_OBJECT))
  1710.          Error ("Cannot use SMOOTH here");
  1711.        ((HEIGHT_FIELD *) Object)->Smoothed = TRUE;
  1712.        Object->Type |= DOUBLE_ILLUMINATE;
  1713.      END_CASE
  1714.  
  1715.      CASE (NO_SHADOW_TOKEN)
  1716.        Object->No_Shadow_Flag = TRUE;
  1717.      END_CASE
  1718.  
  1719.      CASE (LIGHT_SOURCE_TOKEN)
  1720.        Error("Light source must be defined using new syntax");
  1721.      END_CASE
  1722.  
  1723.      OTHERWISE
  1724.        UNGET
  1725.        EXIT
  1726.      END_CASE
  1727.    END_EXPECT
  1728.  
  1729.    if (Object->Bound != NULL)
  1730.      {
  1731. #ifdef DB_CODE
  1732.       /* I don't like this! What if the bounding object's bounding box
  1733.      is larger than the object's bounding box ??? */
  1734. #else
  1735.       Object->Bounds.Lower_Left = Object->Bound->Bounds.Lower_Left;
  1736.       Object->Bounds.Lengths    = Object->Bound->Bounds.Lengths;
  1737. #endif
  1738.      }
  1739.    Parse_End ();
  1740.   }
  1741.  
  1742. static
  1743. OBJECT *Parse_Sphere ()
  1744.   {
  1745.    SPHERE *Object;
  1746.  
  1747.    Parse_Begin ();
  1748.  
  1749.    if ( (Object = (SPHERE *)Parse_Object_Id()) != NULL)
  1750.       return ((OBJECT *) Object);
  1751.       
  1752.    Object = Create_Sphere();
  1753.  
  1754.    Parse_Vector(&(Object -> Center));   Parse_Comma();
  1755.    Object -> Radius = Parse_Float();
  1756.    Object -> Radius_Squared = Object -> Radius * Object -> Radius;
  1757.    Object -> Inverse_Radius = 1.0 / Object -> Radius;
  1758.  
  1759.    Make_Vector(&Object->Bounds.Lower_Left,
  1760.            Object->Center.x - Object->Radius,
  1761.            Object->Center.y - Object->Radius,
  1762.            Object->Center.z - Object->Radius);
  1763.    Make_Vector(&Object->Bounds.Lengths,
  1764.            2.0 * Object->Radius,
  1765.            2.0 * Object->Radius,
  1766.            2.0 * Object->Radius);
  1767.  
  1768.    Parse_Object_Mods ((OBJECT *) Object);
  1769.  
  1770.    return ((OBJECT *) Object);
  1771.   }
  1772.  
  1773. static
  1774. OBJECT *Parse_Plane ()
  1775.   {
  1776.    PLANE *Object;
  1777.  
  1778.    Parse_Begin ();
  1779.  
  1780.    if ( (Object = (PLANE *)Parse_Object_Id()) != NULL)
  1781.       return ((OBJECT *) Object);
  1782.  
  1783.    Object = Create_Plane();
  1784.  
  1785.    Parse_Vector(&(Object -> Normal_Vector));   Parse_Comma();
  1786.    VNormalize(Object->Normal_Vector, Object->Normal_Vector);
  1787.    Object->Distance = -Parse_Float();
  1788.  
  1789.    Parse_Object_Mods ((OBJECT *)Object);
  1790.  
  1791.    return ((OBJECT *) Object);
  1792.   }
  1793.  
  1794. static
  1795. OBJECT *Parse_Height_Field ()
  1796.   {
  1797.    HEIGHT_FIELD *Object;
  1798.    VECTOR Local_Vector;
  1799.    IMAGE *Image;
  1800.  
  1801.    Parse_Begin ();
  1802.  
  1803.    if ( (Object = (HEIGHT_FIELD *)Parse_Object_Id()) != NULL)
  1804.       return ((OBJECT *) Object);
  1805.  
  1806.    Object = Create_Height_Field();
  1807.  
  1808.    Image = Parse_Image (HF_FILE);
  1809.    Image->Use_Colour_Flag = FALSE;
  1810.  
  1811.    Object->bounding_box->bounds[0].x = 1.0;
  1812.    Object->bounding_box->bounds[0].y = 0.0;
  1813.    Object->bounding_box->bounds[0].z = 1.0;
  1814.    if (Image->File_Type == POT_FILE)
  1815.      {
  1816.       Object->bounding_box->bounds[1].x = Image -> width/2.0 - 2.0;
  1817.       Make_Vector(&Local_Vector,2.0/Image->width,1.0/65536.0,1.0/Image->height);
  1818.      }
  1819.    else
  1820.      {
  1821.       Object->bounding_box->bounds[1].x = Image -> width - 2.0;
  1822.       Make_Vector(&Local_Vector,1.0/(Image->width),1.0/65536.0,1.0/(Image->height));
  1823.      }
  1824.    Object->bounding_box->bounds[1].y = 65536.0;
  1825.    Object->bounding_box->bounds[1].z = Image -> height - 2.0;
  1826.    Compute_Scaling_Transform(Object->Trans,&Local_Vector);
  1827.  
  1828.    Parse_Object_Mods ((OBJECT *)Object);
  1829.  
  1830.    Find_Hf_Min_Max(Object, Image);
  1831.  
  1832.    return ((OBJECT *) Object);
  1833.   }
  1834.  
  1835. static
  1836. OBJECT *Parse_Triangle ()
  1837.   {
  1838.    TRIANGLE *Object;
  1839.  
  1840.    Parse_Begin ();
  1841.  
  1842.    if ( (Object = (TRIANGLE *)Parse_Object_Id()) != NULL)
  1843.       return ((OBJECT *) Object);
  1844.       
  1845.    Object = Create_Triangle();
  1846.  
  1847.    Parse_Vector (&Object->P1);    Parse_Comma();
  1848.    Parse_Vector (&Object->P2);    Parse_Comma();
  1849.    Parse_Vector (&Object->P3);
  1850.    if (!Compute_Triangle (Object,FALSE))
  1851.      fprintf (stdout, "Degenerate triangle on line %d.  Please remove.\n",
  1852.           Token.Token_Line_No+1);
  1853.  
  1854.    Parse_Object_Mods ((OBJECT *)Object);
  1855.  
  1856.    return ((OBJECT *) Object);
  1857.   }
  1858.  
  1859. static
  1860. OBJECT *Parse_Smooth_Triangle ()
  1861.   {
  1862.    SMOOTH_TRIANGLE *Object;
  1863.    short degen;                                                   /* LSK */
  1864.    DBL vlen;                                                      /* LSK */
  1865.  
  1866.    degen=FALSE;
  1867.  
  1868.    Parse_Begin ();
  1869.  
  1870.    if ( (Object = (SMOOTH_TRIANGLE *)Parse_Object_Id()) != NULL)
  1871.       return ((OBJECT *) Object);
  1872.  
  1873.    Object = Create_Smooth_Triangle();
  1874.  
  1875.    Parse_Vector (&Object->P1);    Parse_Comma();
  1876.    Parse_Vector (&Object->N1);    Parse_Comma();
  1877.  
  1878.    VLength(vlen,Object->N1);                                     /* LSK */
  1879.    if (vlen<1E-09)                                               /* LSK */
  1880.      degen=TRUE;                                                 /* LSK */
  1881.    else                                                          /* LSK */
  1882.      VNormalize (Object->N1, Object->N1);
  1883.  
  1884.    Parse_Vector (&Object->P2);    Parse_Comma();
  1885.    Parse_Vector (&Object->N2);    Parse_Comma();
  1886.  
  1887.    VLength(vlen,Object->N2);                                     /* LSK */
  1888.    if (vlen<1E-09)                                               /* LSK */
  1889.      degen=TRUE;                                                 /* LSK */
  1890.    else                                                          /* LSK */
  1891.      VNormalize (Object->N2, Object->N2);
  1892.  
  1893.    Parse_Vector (&Object->P3);    Parse_Comma();
  1894.    Parse_Vector (&Object->N3);
  1895.  
  1896.    VLength(vlen,Object->N3);                                     /* LSK */
  1897.    if (vlen<1E-09)                                               /* LSK */
  1898.      degen=TRUE;                                                 /* LSK */
  1899.    else                                                          /* LSK */
  1900.      VNormalize (Object->N3, Object->N3);
  1901.  
  1902.    if (!degen) {                                                 /* LSK */
  1903.      degen=!Compute_Triangle ((TRIANGLE *) Object,TRUE);         /* LSK */
  1904.    }
  1905.  
  1906.    if (degen)                                                    /* LSK */
  1907.      fprintf (stdout, "Degenerate triangle on line %d.  Please remove.\n",
  1908.               Token.Token_Line_No+1);
  1909.  
  1910.    Parse_Object_Mods ((OBJECT *)Object);
  1911.  
  1912.    return ((OBJECT *) Object);
  1913.  }
  1914.  
  1915. static
  1916. OBJECT *Parse_Quadric ()
  1917.   {
  1918.    QUADRIC *Object;
  1919.  
  1920.    Parse_Begin ();
  1921.  
  1922.    if ( (Object = (QUADRIC *)Parse_Object_Id()) != NULL)
  1923.       return ((OBJECT *) Object);
  1924.       
  1925.    Object = Create_Quadric();
  1926.  
  1927.    Parse_Vector(&(Object -> Square_Terms));     Parse_Comma();
  1928.    Parse_Vector(&(Object -> Mixed_Terms));      Parse_Comma();
  1929.    Parse_Vector(&(Object -> Terms));            Parse_Comma();
  1930.    Object -> Constant = Parse_Float();
  1931.    Object -> Non_Zero_Square_Term =
  1932.      !( (Object -> Square_Terms.x == 0.0)
  1933.      && (Object -> Square_Terms.y == 0.0)
  1934.      && (Object -> Square_Terms.z == 0.0)
  1935.      && (Object -> Mixed_Terms.x == 0.0)
  1936.      && (Object -> Mixed_Terms.y == 0.0)
  1937.      && (Object -> Mixed_Terms.z == 0.0));
  1938.  
  1939. #ifdef DB_CODE
  1940.    /* necessary for bounding of quadrics. */
  1941.    Compute_Quadric_BBox(Object);
  1942. #endif
  1943.  
  1944.    Parse_Object_Mods ((OBJECT *)Object);
  1945.    
  1946.    return ((OBJECT *) Object);
  1947.   }
  1948.  
  1949. static
  1950. OBJECT *Parse_Box ()
  1951.   {
  1952.    BOX *Object;
  1953.    DBL temp;
  1954.  
  1955.    Parse_Begin ();
  1956.  
  1957.    if ( (Object = (BOX *)Parse_Object_Id()) != NULL)
  1958.       return ((OBJECT *) Object);
  1959.       
  1960.    Object = Create_Box();
  1961.  
  1962.    Parse_Vector(&(Object->bounds[0]));     Parse_Comma();
  1963.    Parse_Vector(&(Object->bounds[1]));
  1964.  
  1965.     if (Object->bounds[0].x > Object->bounds[1].x) {
  1966.        temp = Object->bounds[0].x;
  1967.        Object->bounds[0].x = Object->bounds[1].x;
  1968.        Object->bounds[1].x = temp;
  1969.        }
  1970.     if (Object->bounds[0].y > Object->bounds[1].y) {
  1971.        temp = Object->bounds[0].y;
  1972.        Object->bounds[0].y = Object->bounds[1].y;
  1973.        Object->bounds[1].y = temp;
  1974.        }
  1975.     if (Object->bounds[0].z > Object->bounds[1].z) {
  1976.        temp = Object->bounds[0].z;
  1977.        Object->bounds[0].z = Object->bounds[1].z;
  1978.        Object->bounds[1].z = temp;
  1979.        }
  1980.  
  1981.    Object->Bounds.Lower_Left = Object->bounds[0];
  1982.    VSub(Object->Bounds.Lengths, Object->bounds[1],Object->bounds[0]);
  1983.  
  1984.    Parse_Object_Mods ((OBJECT *)Object);
  1985.  
  1986.    return ((OBJECT *) Object);
  1987.   }
  1988.  
  1989.  
  1990.  
  1991. static
  1992. OBJECT *Parse_Disc ()
  1993.   {
  1994.    DISC *Object;
  1995.    DBL tmpf;
  1996.    VECTOR lengths;
  1997.  
  1998.    Parse_Begin ();
  1999.  
  2000.    if ( (Object = (DISC *)Parse_Object_Id()) != NULL)
  2001.       return ((OBJECT *) Object);
  2002.       
  2003.    Object = Create_Disc();
  2004.  
  2005.    Parse_Vector(&(Object->center)); Parse_Comma ();
  2006.    Parse_Vector(&(Object->normal)); Parse_Comma ();
  2007.    VNormalize(Object->normal, Object->normal);
  2008.  
  2009.    tmpf = Parse_Float(); Parse_Comma ();
  2010.    Object->oradius2 = tmpf * tmpf;
  2011.  
  2012.    EXPECT
  2013.      CASE_FLOAT
  2014.        tmpf = Parse_Float();
  2015.        Object->iradius2 = tmpf * tmpf;
  2016.      END_CASE
  2017.  
  2018.      OTHERWISE
  2019.        UNGET
  2020.        EXIT
  2021.      END_CASE
  2022.    END_EXPECT
  2023.  
  2024.    /* Calculate info needed for ray-disc intersections */
  2025.    VDot(tmpf, Object->center, Object->normal);
  2026.    Object->d = -tmpf;
  2027.  
  2028.    /* Calculate the bounds */
  2029.    tmpf = sqrt(Object->oradius2);
  2030.    Make_Vector(&lengths, tmpf, tmpf, tmpf);
  2031.    VSub(Object->Bounds.Lower_Left, Object->center, lengths);
  2032.    VScale(Object->Bounds.Lengths, lengths, 2.0);
  2033.  
  2034.    Parse_Object_Mods ((OBJECT *)Object);
  2035.  
  2036.    return ((OBJECT *) Object);
  2037.   }
  2038.  
  2039. static
  2040. OBJECT *Parse_Cylinder ()
  2041.   {
  2042.    CONE *Object;
  2043.  
  2044.    Parse_Begin ();
  2045.  
  2046.    if ( (Object = (CONE *)Parse_Object_Id()) != NULL)
  2047.       return ((OBJECT *) Object);
  2048.       
  2049.    Object = Create_Cylinder();
  2050.  
  2051.    Parse_Vector(&(Object->apex));  Parse_Comma ();
  2052.    Parse_Vector(&(Object->base));  Parse_Comma ();
  2053.    Object->apex_radius = Parse_Float();
  2054.    Object->base_radius = Object->apex_radius;
  2055.  
  2056.    EXPECT
  2057.      CASE(OPEN_TOKEN)
  2058.        Object->closed = 0;
  2059.        EXIT
  2060.      END_CASE
  2061.      
  2062.      OTHERWISE
  2063.        UNGET
  2064.        EXIT
  2065.      END_CASE
  2066.    END_EXPECT
  2067.  
  2068.    Compute_Cylinder_Data((OBJECT *)Object);
  2069.  
  2070.    Parse_Object_Mods ((OBJECT *)Object);
  2071.  
  2072.    return ((OBJECT *) Object);
  2073.   }
  2074.  
  2075. static
  2076. OBJECT *Parse_Cone ()
  2077.   {
  2078.    CONE *Object;
  2079.  
  2080.    Parse_Begin ();
  2081.  
  2082.    if ( (Object = (CONE *)Parse_Object_Id()) != NULL)
  2083.       return ((OBJECT *) Object);
  2084.       
  2085.    Object = Create_Cone();
  2086.  
  2087.    Parse_Vector(&(Object->apex));  Parse_Comma ();
  2088.    Object->apex_radius = Parse_Float();  Parse_Comma ();
  2089.  
  2090.    Parse_Vector(&(Object->base));  Parse_Comma ();
  2091.    Object->base_radius = Parse_Float();
  2092.    
  2093.    EXPECT
  2094.      CASE(OPEN_TOKEN)
  2095.        Object->closed = 0;
  2096.        EXIT
  2097.      END_CASE
  2098.      
  2099.      OTHERWISE
  2100.        UNGET
  2101.        EXIT
  2102.      END_CASE
  2103.    END_EXPECT
  2104.  
  2105.    /* Compute run-time values for the cone */
  2106.    Compute_Cone_Data((OBJECT *)Object);
  2107.  
  2108.    Parse_Object_Mods ((OBJECT *)Object);
  2109.  
  2110.    return ((OBJECT *) Object);
  2111.   }
  2112.  
  2113. static
  2114. OBJECT *Parse_Blob ()
  2115.   {
  2116.    BLOB *Object;
  2117.    DBL threshold;
  2118.    int npoints;
  2119.    blobstackptr blob_components, blob_component;
  2120.  
  2121.    Parse_Begin ();
  2122.  
  2123.    if ( (Object = (BLOB *)Parse_Object_Id()) != NULL)
  2124.       return ((OBJECT *) Object);
  2125.       
  2126.    Object = Create_Blob();
  2127.  
  2128.    blob_components = NULL;
  2129.    npoints = 0;
  2130.    threshold = 1.0;
  2131.  
  2132.    EXPECT
  2133.      CASE (THRESHOLD_TOKEN)
  2134.        threshold = Parse_Float();
  2135.      END_CASE
  2136.  
  2137.      CASE (COMPONENT_TOKEN)
  2138.        blob_component = (blobstackptr) malloc(sizeof(struct blob_list_struct));
  2139.        if (blob_component == NULL)
  2140.           MAError("blob component");
  2141.        blob_component->elem.coeffs[2] = Parse_Float(); Parse_Comma();
  2142.        blob_component->elem.radius2   = Parse_Float(); Parse_Comma();
  2143.        Parse_Vector(&blob_component->elem.pos);
  2144.        blob_component->next = blob_components;
  2145.        blob_components = blob_component;
  2146.        npoints++;
  2147.      END_CASE
  2148.  
  2149.      OTHERWISE
  2150.        UNGET
  2151.        EXIT
  2152.      END_CASE
  2153.    END_EXPECT
  2154.  
  2155.    /* Finally, process the information */
  2156.    MakeBlob(Object, threshold, blob_components, npoints, 0);
  2157.  
  2158.    Parse_Object_Mods ((OBJECT *)Object);
  2159.  
  2160.    return ((OBJECT *) Object);
  2161.   }
  2162.  
  2163. static
  2164. OBJECT *Parse_Torus ()
  2165.   {
  2166.    POLY *Object;
  2167.    DBL iradius, oradius, *Coeffs;
  2168.  
  2169.    Parse_Begin ();
  2170.  
  2171.    if ( (Object = (POLY *)Parse_Object_Id()) != NULL)
  2172.       return ((OBJECT *) Object);
  2173.       
  2174.    Object = Create_Poly(4);
  2175.  
  2176.    /* Read in the two radii */
  2177.    iradius = Parse_Float(); /* Big radius */
  2178.    Parse_Comma();
  2179.    oradius = Parse_Float(); /* Little radius */
  2180.  
  2181.    /* Build the coefficients of a torus lying in the x-z plane */
  2182.    Coeffs = Object->Coeffs;
  2183.    Coeffs[ 0] =  1.0;
  2184.    Coeffs[ 4] =  2.0;
  2185.    Coeffs[ 7] =  2.0;
  2186.    Coeffs[ 9] = -2.0 * (iradius * iradius + oradius * oradius);
  2187.    Coeffs[20] =  1.0;
  2188.    Coeffs[23] =  2.0;
  2189.    Coeffs[25] =  2.0 * (iradius * iradius - oradius * oradius);
  2190.    Coeffs[30] =  1.0;
  2191.    Coeffs[32] = -2.0 * (iradius * iradius + oradius * oradius);
  2192.    Coeffs[34] = (iradius * iradius - oradius * oradius) *
  2193.             (iradius * iradius - oradius * oradius);
  2194.  
  2195.    Make_Vector(&Object->Bounds.Lower_Left, -(iradius + oradius),
  2196.            -iradius, -(iradius + oradius))
  2197.    Make_Vector(&Object->Bounds.Lengths, 2.0 * (iradius + oradius),
  2198.            2.0 * iradius, 2.0 * (iradius + oradius));
  2199.  
  2200.    Parse_Object_Mods ((OBJECT *)Object);
  2201.  
  2202.    return ((OBJECT *) Object);
  2203.   }
  2204.  
  2205. static
  2206. OBJECT *Parse_Poly (order)
  2207.   int order;
  2208.   {
  2209.    POLY *Object;
  2210.  
  2211.    Parse_Begin ();
  2212.  
  2213.    if ( (Object = (POLY *)Parse_Object_Id()) != NULL)
  2214.       return ((OBJECT *) Object);
  2215.       
  2216.    if (order == 0)
  2217.      {
  2218.       order = (int)Parse_Float();      Parse_Comma();
  2219.       if (order < 2 || order > MAX_ORDER)
  2220.         Error("Order of poly is out of range");
  2221.      }
  2222.  
  2223.    Object = Create_Poly(order);
  2224.  
  2225.    Parse_Coeffs(Object->Order, &(Object->Coeffs[0]));
  2226.  
  2227.    Parse_Object_Mods ((OBJECT *)Object);
  2228.  
  2229.    return ((OBJECT *) Object);
  2230.   }
  2231.  
  2232. static
  2233. OBJECT *Parse_Bicubic_Patch ()
  2234.   {
  2235.    BICUBIC_PATCH *Object;
  2236.    int i, j;
  2237.  
  2238.    Parse_Begin ();
  2239.  
  2240.    if ( (Object = (BICUBIC_PATCH *)Parse_Object_Id()) != NULL)
  2241.       return ((OBJECT *) Object);
  2242.       
  2243.    Object = Create_Bicubic_Patch();
  2244.  
  2245.    EXPECT
  2246.      CASE_FLOAT
  2247.        Warn("Should use keywords for bicubic parameters.",1.5);
  2248.        Object->Patch_Type = (int)Parse_Float();
  2249.        if (Object->Patch_Type == 2 ||
  2250.            Object->Patch_Type == 3)
  2251.            Object->Flatness_Value = Parse_Float();
  2252.          else
  2253.            Object->Flatness_Value = 0.1;
  2254.        Object->U_Steps = (int)Parse_Float();
  2255.        Object->V_Steps = (int)Parse_Float();
  2256.        EXIT
  2257.      END_CASE       
  2258.        
  2259.      CASE (TYPE_TOKEN)
  2260.        Object->Patch_Type = (int)Parse_Float();
  2261.      END_CASE
  2262.  
  2263.      CASE (FLATNESS_TOKEN)
  2264.        Object->Flatness_Value = Parse_Float();
  2265.      END_CASE
  2266.  
  2267.      CASE (V_STEPS_TOKEN)
  2268.        Object->V_Steps = (int)Parse_Float();
  2269.      END_CASE
  2270.  
  2271.      CASE (U_STEPS_TOKEN)
  2272.        Object->U_Steps = (int)Parse_Float();
  2273.      END_CASE
  2274.  
  2275.      OTHERWISE
  2276.        UNGET
  2277.        EXIT
  2278.      END_CASE
  2279.    END_EXPECT
  2280.  
  2281.    if (Object->Patch_Type > 1)
  2282.      {
  2283.       Object->Patch_Type = 1;
  2284.       Warn("Patch type no longer supported. Using type 1.",0.0);
  2285.      }
  2286.  
  2287.    if ((Object->Patch_Type < 0) || (Object->Patch_Type > MAX_PATCH_TYPE))
  2288.      Error("Undefined bicubic patch type");
  2289.  
  2290.    Parse_Comma();
  2291.    for (i=0;i<4;i++)
  2292.      for (j=0;j<4;j++)
  2293.        {
  2294.         Parse_Vector(&(Object -> Control_Points[i][j]));
  2295.         if (!((i==3)&&(j==3)))
  2296.           Parse_Comma();
  2297.        };
  2298.    Precompute_Patch_Values(Object); /* interpolated mesh coords */
  2299.  
  2300.    Parse_Object_Mods ((OBJECT *)Object);
  2301.  
  2302.    return ((OBJECT *) Object);
  2303.   }
  2304.  
  2305. static
  2306. OBJECT *Parse_CSG (CSG_Type)
  2307.   int CSG_Type;
  2308.   {
  2309.    CSG *Object;
  2310.    OBJECT *Local;
  2311.    int Object_Count = 0;
  2312.  
  2313.    Parse_Begin ();
  2314.  
  2315.    if ( (Object = (CSG *)Parse_Object_Id()) != NULL)
  2316.       return ((OBJECT *) Object);
  2317.       
  2318.    if (CSG_Type & CSG_UNION_TYPE)
  2319.      Object = Create_CSG_Union ();
  2320.    else
  2321.      if (CSG_Type & CSG_MERGE_TYPE)
  2322.        Object = Create_CSG_Merge ();
  2323.      else
  2324.        Object = Create_CSG_Intersection ();
  2325.  
  2326.    Object->Children = NULL;
  2327.  
  2328.    while ((Local = Parse_Object ()) != NULL)
  2329.      {
  2330.       if ((CSG_Type & CSG_INTERSECTION_TYPE) && (Local->Type & PATCH_OBJECT))
  2331.         Warn ("Patch objects not allowed in intersection",0.0);
  2332.       Object_Count++;
  2333.       if ((CSG_Type & CSG_DIFFERENCE_TYPE) && (Object_Count > 1))
  2334.         Invert_Object (Local);
  2335.       Object->Type |=  (Local->Type & CHILDREN_FLAGS);
  2336.       Local->Type |= IS_CHILD_OBJECT;
  2337.       Link(Local, &Local->Sibling, &Object->Children);
  2338.      };
  2339.  
  2340.    if ((Object_Count < 2) && (Language_Version >= 1.5))
  2341.      Warn ("Should have at least 2 objects in csg",1.5);
  2342.    Compute_CSG_Bounds((OBJECT *)Object);
  2343.  
  2344.    Parse_Object_Mods ((OBJECT *)Object);
  2345.  
  2346.    return ((OBJECT *) Object);
  2347.   }
  2348.  
  2349. static
  2350. OBJECT *Parse_Light_Source ()
  2351.   {
  2352.    VECTOR Local_Vector;
  2353.    LIGHT_SOURCE *Object;
  2354.  
  2355.    Parse_Begin ();
  2356.  
  2357.    if ( (Object = (LIGHT_SOURCE *)Parse_Object_Id()) != NULL)
  2358.       return ((OBJECT *) Object);
  2359.       
  2360.    Object = Create_Light_Source ();
  2361.  
  2362.    Parse_Vector(&Object->Center);
  2363.  
  2364.    GET (COLOUR_TOKEN)
  2365.  
  2366.    Parse_Colour (&Object->Colour);
  2367.  
  2368.    EXPECT
  2369.      CASE (LOOKS_LIKE_TOKEN)
  2370.        if (Object->Children != NULL)
  2371.          Error("Only one looks_like allowed per light_source");
  2372.        Parse_Begin ();
  2373.        Object->Type &= ~(int)PATCH_OBJECT;
  2374.        if ((Object->Children = Parse_Object ()) == NULL)
  2375.          Parse_Error_Str ("object");
  2376.        Translate_Object (Object->Children, &Object->Center);
  2377.        Parse_Object_Mods (Object->Children);
  2378.        Object->Children->No_Shadow_Flag = TRUE;
  2379.        Object->No_Shadow_Flag = TRUE;
  2380.        Object->Type |= (Object->Children->Type & CHILDREN_FLAGS);
  2381.      END_CASE
  2382.  
  2383.      CASE (SPOTLIGHT_TOKEN)
  2384.        Object->Light_Type = SPOT_SOURCE;
  2385.      END_CASE
  2386.  
  2387.      CASE (POINT_AT_TOKEN)
  2388.        if (Object->Light_Type == SPOT_SOURCE)
  2389.          Parse_Vector(&Object->Points_At);
  2390.        else
  2391.          Error("Spotlight param illegal in standard light source");
  2392.      END_CASE
  2393.  
  2394.      CASE (TIGHTNESS_TOKEN)
  2395.        if (Object->Light_Type == SPOT_SOURCE)
  2396.          Object->Coeff = Parse_Float();
  2397.        else
  2398.          Error("Spotlight param illegal in standard light source");
  2399.      END_CASE
  2400.  
  2401.      CASE (RADIUS_TOKEN)
  2402.        if (Object->Light_Type == SPOT_SOURCE)
  2403.          Object->Radius = cos(Parse_Float() * M_PI / 180.0);
  2404.        else
  2405.          Error("Spotlight param illegal in standard light source");
  2406.      END_CASE
  2407.  
  2408.      CASE (FALLOFF_TOKEN)
  2409.        if (Object->Light_Type == SPOT_SOURCE)
  2410.          Object->Falloff = cos(Parse_Float() * M_PI / 180.0);
  2411.        else
  2412.          Error("Spotlight param illegal in standard light source");
  2413.      END_CASE
  2414.  
  2415.      CASE (AREA_LIGHT_TOKEN)
  2416.        Object -> Area_Light = TRUE;
  2417.        Parse_Vector (&(Object -> Axis1)); Parse_Comma ();
  2418.        Parse_Vector (&(Object -> Axis2)); Parse_Comma ();
  2419.        Object -> Area_Size1 = (int)Parse_Float(); Parse_Comma ();
  2420.        Object -> Area_Size2 = (int)Parse_Float();
  2421.        Object -> Light_Grid = Create_Light_Grid (Object -> Area_Size1,
  2422.             Object -> Area_Size2);
  2423.      END_CASE
  2424.  
  2425.      CASE (JITTER_TOKEN)
  2426.        Object -> Jitter = TRUE;
  2427.      END_CASE
  2428.  
  2429.      CASE (TRACK_TOKEN)
  2430.        Object -> Track = TRUE;
  2431.      END_CASE
  2432.  
  2433.      CASE (ADAPTIVE_TOKEN)
  2434.        Object -> Adaptive_Level = (int)Parse_Float();
  2435.      END_CASE
  2436.  
  2437.      CASE (TRANSLATE_TOKEN)
  2438.        Parse_Vector (&Local_Vector);
  2439.        Translate_Object ((OBJECT *)Object, &Local_Vector);
  2440.      END_CASE
  2441.  
  2442.      CASE (ROTATE_TOKEN)
  2443.        Parse_Vector (&Local_Vector);
  2444.        Rotate_Object ((OBJECT *)Object, &Local_Vector);
  2445.      END_CASE
  2446.  
  2447.      CASE (SCALE_TOKEN)
  2448.        Parse_Scale_Vector (&Local_Vector);
  2449.        Scale_Object ((OBJECT *)Object, &Local_Vector);
  2450.      END_CASE
  2451.  
  2452.      CASE (TRANSFORM_TOKEN)
  2453.        GET(TRANSFORM_ID_TOKEN)
  2454.        Transform_Object ((OBJECT *)Object, (TRANSFORM *)Token.Constant_Data);
  2455.      END_CASE
  2456.  
  2457.      OTHERWISE
  2458.        UNGET
  2459.        EXIT
  2460.      END_CASE
  2461.    END_EXPECT
  2462.  
  2463.    Parse_End ();
  2464.  
  2465.    return ((OBJECT *)Object);
  2466.   }
  2467.  
  2468.  
  2469. static
  2470. OBJECT *Parse_Object ()
  2471.   {
  2472.    OBJECT *Object = NULL;
  2473.  
  2474.    EXPECT
  2475.      CASE (SPHERE_TOKEN)
  2476.        Object = Parse_Sphere ();
  2477.        EXIT
  2478.      END_CASE
  2479.  
  2480.      CASE (PLANE_TOKEN)
  2481.        Object = Parse_Plane ();
  2482.        EXIT
  2483.      END_CASE
  2484.  
  2485.      CASE (CONE_TOKEN)
  2486.        Object = Parse_Cone ();
  2487.        EXIT
  2488.      END_CASE
  2489.  
  2490.      CASE (CYLINDER_TOKEN)
  2491.        Object = Parse_Cylinder ();
  2492.        EXIT
  2493.      END_CASE
  2494.  
  2495.      CASE (DISC_TOKEN)
  2496.        Object = Parse_Disc ();
  2497.        EXIT
  2498.      END_CASE
  2499.  
  2500.      CASE (QUADRIC_TOKEN)
  2501.        Object = Parse_Quadric ();
  2502.        EXIT
  2503.      END_CASE
  2504.  
  2505.      CASE (CUBIC_TOKEN)
  2506.        Object = Parse_Poly (3);
  2507.        EXIT
  2508.      END_CASE
  2509.  
  2510.      CASE (QUARTIC_TOKEN)
  2511.        Object = Parse_Poly (4);
  2512.        EXIT
  2513.      END_CASE
  2514.  
  2515.      CASE (POLY_TOKEN)
  2516.        Object = Parse_Poly (0);
  2517.        EXIT
  2518.      END_CASE
  2519.  
  2520.      CASE (TORUS_TOKEN)
  2521.        Object = Parse_Torus ();
  2522.        EXIT
  2523.      END_CASE
  2524.  
  2525.      CASE (OBJECT_ID_TOKEN)
  2526.        Object = Copy_Object((OBJECT *) Token.Constant_Data);
  2527.        EXIT
  2528.      END_CASE
  2529.  
  2530.      CASE (UNION_TOKEN)
  2531.        Object = Parse_CSG (CSG_UNION_TYPE);
  2532.        EXIT
  2533.      END_CASE
  2534.  
  2535.      CASE (COMPOSITE_TOKEN)
  2536.        Warn("Use union instead of composite",1.5);
  2537.        Object = Parse_CSG (CSG_UNION_TYPE);
  2538.        EXIT
  2539.      END_CASE
  2540.  
  2541.      CASE (MERGE_TOKEN)
  2542.        Object = Parse_CSG (CSG_MERGE_TYPE);
  2543.        EXIT
  2544.      END_CASE
  2545.  
  2546.      CASE (INTERSECTION_TOKEN)
  2547.        Object = Parse_CSG (CSG_INTERSECTION_TYPE);
  2548.        EXIT
  2549.      END_CASE
  2550.  
  2551.      CASE (DIFFERENCE_TOKEN)
  2552.        Object = Parse_CSG (CSG_DIFFERENCE_TYPE+CSG_INTERSECTION_TYPE);
  2553.        EXIT
  2554.      END_CASE
  2555.  
  2556.      CASE (BICUBIC_PATCH_TOKEN)
  2557.        Object = Parse_Bicubic_Patch ();
  2558.        EXIT
  2559.      END_CASE
  2560.  
  2561.      CASE (TRIANGLE_TOKEN)
  2562.        Object = Parse_Triangle ();
  2563.        EXIT
  2564.      END_CASE
  2565.  
  2566.      CASE (SMOOTH_TRIANGLE_TOKEN)
  2567.        Object = Parse_Smooth_Triangle ();
  2568.        EXIT
  2569.      END_CASE
  2570.  
  2571.      CASE (HEIGHT_FIELD_TOKEN)
  2572.        Object = Parse_Height_Field ();
  2573.        EXIT
  2574.      END_CASE
  2575.  
  2576.      CASE (BOX_TOKEN)
  2577.        Object = Parse_Box ();
  2578.        EXIT
  2579.      END_CASE
  2580.  
  2581.      CASE (BLOB_TOKEN)
  2582.        Object = Parse_Blob ();
  2583.        EXIT
  2584.      END_CASE
  2585.  
  2586.      CASE (LIGHT_SOURCE_TOKEN)
  2587.        Object = Parse_Light_Source ();
  2588.        EXIT
  2589.      END_CASE
  2590.  
  2591.      CASE (OBJECT_TOKEN)
  2592.        Parse_Begin ();
  2593.        Object = Parse_Object ();
  2594.        if (!Object)
  2595.          Parse_Error_Str ("object");
  2596.        Parse_Object_Mods ((OBJECT *)Object);
  2597.        EXIT
  2598.      END_CASE
  2599.  
  2600.      OTHERWISE
  2601.        UNGET
  2602.        EXIT
  2603.      END_CASE
  2604.    END_EXPECT
  2605.  
  2606.    return ((OBJECT *) Object);
  2607.   }
  2608.  
  2609. static void Parse_Fog ()
  2610.   {
  2611.    Parse_Begin ();
  2612.  
  2613.    EXPECT
  2614.      CASE (COLOUR_TOKEN)
  2615.        Parse_Colour (&Frame.Fog_Colour);
  2616.      END_CASE
  2617.  
  2618.      CASE (DISTANCE_TOKEN)
  2619.        Frame.Fog_Distance = Parse_Float ();
  2620.      END_CASE
  2621.  
  2622.      CASE_FLOAT
  2623.        Warn("Should use distance keyword.",1.5);
  2624.        Frame.Fog_Distance = Parse_Float ();
  2625.      END_CASE
  2626.  
  2627.      OTHERWISE
  2628.        UNGET
  2629.        EXIT
  2630.      END_CASE
  2631.    END_EXPECT
  2632.    Parse_End ();
  2633.   }
  2634.  
  2635. static void Parse_Frame ()
  2636.   {
  2637.    OBJECT *Object;
  2638.    TEXTURE *Local_Texture;
  2639.    PIGMENT *Local_Pigment;
  2640.    TNORMAL *Local_Tnormal;
  2641.    FINISH  *Local_Finish;
  2642.  
  2643.    EXPECT
  2644.      CASE (FOG_TOKEN)
  2645.        Parse_Fog();
  2646.      END_CASE
  2647.  
  2648.      CASE (BACKGROUND_TOKEN)
  2649.        Parse_Begin();
  2650.        GET (COLOUR_TOKEN)
  2651.        Parse_Colour (&Frame.Background_Colour);
  2652.        Parse_End();
  2653.      END_CASE
  2654.  
  2655.      CASE (CAMERA_TOKEN)
  2656.        Parse_Camera (&Frame.Camera);
  2657.      END_CASE
  2658.  
  2659.      CASE (DECLARE_TOKEN)
  2660.        Parse_Declare ();
  2661.      END_CASE
  2662.  
  2663.      CASE (MAX_TRACE_LEVEL_TOKEN)
  2664.        Max_Trace_Level = Parse_Float ();
  2665.      END_CASE
  2666.  
  2667.      CASE (VERSION_TOKEN)
  2668.        Language_Version = Parse_Float ();
  2669.      END_CASE
  2670.  
  2671.      CASE (MAX_INTERSECTIONS)
  2672.        Max_Intersections = (int)Parse_Float ();
  2673.      END_CASE
  2674.  
  2675.      CASE (DEFAULT_TOKEN)
  2676.        Not_In_Default = FALSE;
  2677.        Parse_Begin();
  2678.        EXPECT
  2679.          CASE (TEXTURE_TOKEN)
  2680.            Local_Texture = Default_Texture;
  2681.            Default_Texture = Parse_Texture();
  2682.            if (Default_Texture->Type != PNF_TEXTURE)
  2683.              Error("Default texture cannot be material map or tiles");
  2684.            if (Default_Texture->Next_Layer != NULL)
  2685.              Error("Default texture cannot be layered");
  2686.            Destroy_Textures(Local_Texture);
  2687.          END_CASE
  2688.  
  2689.          CASE (PIGMENT_TOKEN)
  2690.            Local_Pigment = Copy_Pigment((Default_Texture->Pigment));
  2691.            Parse_Pigment (&Local_Pigment);
  2692.            Destroy_Pigment(Default_Texture->Pigment);
  2693.            Default_Texture->Pigment = Local_Pigment;
  2694.          END_CASE
  2695.  
  2696.          CASE (TNORMAL_TOKEN)
  2697.            Local_Tnormal = Copy_Tnormal((Default_Texture->Tnormal));
  2698.            Parse_Tnormal (&Local_Tnormal);
  2699.            Destroy_Tnormal(Default_Texture->Tnormal);
  2700.            Default_Texture->Tnormal = Local_Tnormal;
  2701.          END_CASE
  2702.  
  2703.          CASE (FINISH_TOKEN)
  2704.            Local_Finish = Copy_Finish((Default_Texture->Finish));
  2705.            Parse_Finish (&Local_Finish);
  2706.            Destroy_Finish(Default_Texture->Finish);
  2707.            Default_Texture->Finish = Local_Finish;
  2708.          END_CASE
  2709.  
  2710.          CASE (CAMERA_TOKEN)
  2711.        Parse_Camera (&Default_Camera);
  2712.          END_CASE
  2713.  
  2714.          OTHERWISE
  2715.            UNGET
  2716.            EXIT
  2717.          END_CASE
  2718.        END_EXPECT
  2719.        Parse_End();
  2720.        Not_In_Default = TRUE;
  2721.      END_CASE
  2722.  
  2723.      CASE (END_OF_FILE_TOKEN)
  2724.        EXIT
  2725.      END_CASE
  2726.  
  2727.      OTHERWISE
  2728.        UNGET
  2729.        Object = Parse_Object();
  2730.        if (Object == NULL)
  2731.          Parse_Error_Str ("object or directive");
  2732.        Post_Process (Object, NULL);
  2733.        Link_To_Frame (Object);
  2734.      END_CASE
  2735.    END_EXPECT
  2736.   }
  2737.  
  2738. static void Parse_Camera (Camera_Ptr)
  2739.   CAMERA **Camera_Ptr;
  2740.   {
  2741.    VECTOR Local_Vector, Temp_Vector;
  2742.    DBL Direction_Length, Up_Length, Right_Length, Handedness;
  2743.    CAMERA *New;
  2744.  
  2745.    Parse_Begin ();
  2746.  
  2747.    EXPECT
  2748.      CASE (CAMERA_ID_TOKEN)
  2749.        Destroy_Camera(*Camera_Ptr);
  2750.        *Camera_Ptr = Copy_Camera ((CAMERA *) Token.Constant_Data);
  2751.        EXIT
  2752.      END_CASE
  2753.  
  2754.      OTHERWISE
  2755.        UNGET
  2756.        EXIT
  2757.      END_CASE
  2758.    END_EXPECT
  2759.  
  2760.    New = *Camera_Ptr;
  2761.  
  2762.    EXPECT
  2763.      CASE (LOCATION_TOKEN)
  2764.        Parse_Vector(&(New->Location));
  2765.      END_CASE
  2766.  
  2767.      CASE (DIRECTION_TOKEN)
  2768.        Parse_Vector(&(New->Direction));
  2769.      END_CASE
  2770.  
  2771.      CASE (UP_TOKEN)
  2772.        Parse_Vector(&(New->Up));
  2773.      END_CASE
  2774.  
  2775.      CASE (RIGHT_TOKEN)
  2776.        Parse_Vector(&(New->Right));
  2777.      END_CASE
  2778.  
  2779.      CASE (SKY_TOKEN)
  2780.        Parse_Vector(&(New->Sky));
  2781.      END_CASE
  2782.  
  2783.      CASE (LOOK_AT_TOKEN)
  2784.        VLength (Direction_Length, New->Direction);
  2785.        VLength (Up_Length,        New->Up);
  2786.        VLength (Right_Length,     New->Right);
  2787.        VCross  (Temp_Vector,      New->Direction, New->Up);
  2788.        VDot    (Handedness,       Temp_Vector,   New->Right);
  2789.  
  2790.        Parse_Vector (&New->Direction);
  2791.  
  2792.        VSub       (New->Direction, New->Direction, New->Location);
  2793.        VNormalize (New->Direction, New->Direction);
  2794.        VCross     (New->Right,     New->Direction, New->Sky);
  2795.        VNormalize (New->Right,     New->Right);
  2796.        VCross     (New->Up,        New->Right,     New->Direction);
  2797.        VScale     (New->Direction, New->Direction, Direction_Length);
  2798.  
  2799.        if (Handedness >= 0.0)
  2800.      VScale (New->Right, New->Right, Right_Length)
  2801.        else
  2802.      VScale (New->Right, New->Right, -Right_Length);
  2803.  
  2804.        VScale (New->Up, New->Up, Up_Length);
  2805.      END_CASE
  2806.  
  2807.      CASE (TRANSLATE_TOKEN)
  2808.        Parse_Vector (&Local_Vector);
  2809.        Translate_Camera (New, &Local_Vector);
  2810.      END_CASE
  2811.  
  2812.      CASE (ROTATE_TOKEN)
  2813.        Parse_Vector (&Local_Vector);
  2814.        Rotate_Camera (New, &Local_Vector);
  2815.      END_CASE
  2816.  
  2817.      CASE (SCALE_TOKEN)
  2818.        Parse_Scale_Vector (&Local_Vector);
  2819.        Scale_Camera (New, &Local_Vector);
  2820.      END_CASE
  2821.  
  2822.      CASE (TRANSFORM_TOKEN)
  2823.        GET(TRANSFORM_ID_TOKEN)
  2824.        Transform_Camera (New, (TRANSFORM *)Token.Constant_Data);
  2825.      END_CASE
  2826.  
  2827.      OTHERWISE
  2828.        UNGET
  2829.        EXIT
  2830.      END_CASE
  2831.    END_EXPECT
  2832.    Parse_End ();
  2833.   }
  2834.  
  2835. static
  2836. TRANSFORM *Parse_Transform ()
  2837.   {
  2838.    TRANSFORM *New, Local_Trans;
  2839.    VECTOR Local_Vector;
  2840.  
  2841.    Parse_Begin ();
  2842.    New = Create_Transform ();
  2843.  
  2844.    EXPECT
  2845.      CASE(TRANSFORM_ID_TOKEN)
  2846.        Compose_Transforms (New, (TRANSFORM *)Token.Constant_Data);
  2847.        EXIT
  2848.      END_CASE
  2849.  
  2850.      CASE (TRANSLATE_TOKEN)
  2851.        Parse_Vector (&Local_Vector);
  2852.        Compute_Translation_Transform(&Local_Trans, &Local_Vector);
  2853.        Compose_Transforms (New, &Local_Trans);
  2854.      END_CASE
  2855.  
  2856.      CASE (ROTATE_TOKEN)
  2857.        Parse_Vector (&Local_Vector);
  2858.        Compute_Rotation_Transform(&Local_Trans, &Local_Vector);
  2859.        Compose_Transforms (New, &Local_Trans);
  2860.      END_CASE
  2861.  
  2862.      CASE (SCALE_TOKEN)
  2863.        Parse_Scale_Vector (&Local_Vector);
  2864.        Compute_Scaling_Transform(&Local_Trans, &Local_Vector);
  2865.        Compose_Transforms (New, &Local_Trans);
  2866.      END_CASE
  2867.  
  2868.      OTHERWISE
  2869.        UNGET
  2870.        EXIT
  2871.      END_CASE
  2872.    END_EXPECT
  2873.  
  2874.    Parse_End ();
  2875.    return (New);
  2876.   }
  2877.  
  2878. static void Parse_Declare ()
  2879.   {
  2880.   VECTOR Local_Vector;
  2881.   COLOUR *Local_Colour;
  2882.   PIGMENT *Local_Pigment;
  2883.   TNORMAL *Local_Tnormal;
  2884.   FINISH *Local_Finish;
  2885.   TEXTURE *Local_Texture;
  2886.   COLOUR_MAP *Local_Colour_Map;
  2887.   TRANSFORM *Local_Trans;
  2888.   OBJECT *Local_Object;
  2889.   CAMERA *Local_Camera;
  2890.  
  2891.   struct Constant_Struct *Constant_Ptr;
  2892.  
  2893.   EXPECT
  2894.     CASE (IDENTIFIER_TOKEN)
  2895.       if (++Number_Of_Constants >= MAX_CONSTANTS)
  2896.         Error ("Too many constants \"DECLARED\"");
  2897.       else
  2898.         Constant_Ptr = &(Constants[Number_Of_Constants]);
  2899.       EXIT
  2900.     END_CASE
  2901.  
  2902.     CASE4 (COLOUR_ID_TOKEN, VECTOR_ID_TOKEN, FLOAT_ID_TOKEN, PIGMENT_ID_TOKEN)
  2903.     CASE4 (TNORMAL_ID_TOKEN, FINISH_ID_TOKEN, TEXTURE_ID_TOKEN, OBJECT_ID_TOKEN)
  2904.     CASE3 (COLOUR_MAP_ID_TOKEN, TRANSFORM_ID_TOKEN, CAMERA_ID_TOKEN)
  2905.       Constant_Ptr = &(Constants[Token.Constant_Index]);
  2906.       EXIT
  2907.     END_CASE
  2908.  
  2909.     OTHERWISE
  2910.       Parse_Error(IDENTIFIER_TOKEN);
  2911.     END_CASE
  2912.   END_EXPECT
  2913.  
  2914.   Previous = Token.Token_Id;
  2915.  
  2916.   GET (EQUALS_TOKEN);
  2917.  
  2918.   EXPECT
  2919.     CASE (COLOUR_TOKEN)
  2920.       if (Test_Redefine(COLOUR_ID_TOKEN))
  2921.         Destroy_Colour((COLOUR *)Constant_Ptr->Constant_Data);
  2922.       Local_Colour = Create_Colour();
  2923.       Parse_Colour (Local_Colour);
  2924.       Constant_Ptr -> Constant_Data = (char *) Local_Colour;
  2925.       Constant_Ptr -> Constant_Type = COLOUR_CONSTANT;
  2926.       EXIT
  2927.     END_CASE
  2928.  
  2929.     CASE_VECTOR
  2930.       Have_Vector = FALSE;
  2931.       Parse_Vector_Float (&Local_Vector);
  2932.       if (Have_Vector)
  2933.         {
  2934.          if (Test_Redefine(VECTOR_ID_TOKEN))
  2935.            Destroy_Vector((VECTOR *)Constant_Ptr->Constant_Data);
  2936.          Constant_Ptr -> Constant_Type = VECTOR_CONSTANT;
  2937.          Constant_Ptr -> Constant_Data = (char *) Create_Vector();
  2938.          *((VECTOR *)Constant_Ptr -> Constant_Data) = Local_Vector;
  2939.         }
  2940.       else
  2941.         {
  2942.          if (Test_Redefine(FLOAT_ID_TOKEN))
  2943.            Destroy_Float((DBL *)Constant_Ptr->Constant_Data);
  2944.          Constant_Ptr -> Constant_Type = FLOAT_CONSTANT;
  2945.          Constant_Ptr -> Constant_Data = (char *) Create_Float();
  2946.          *((DBL *) Constant_Ptr -> Constant_Data) = Local_Vector.x;
  2947.         }
  2948.       EXIT
  2949.     END_CASE
  2950.  
  2951.     CASE (PIGMENT_TOKEN)
  2952.       if (Test_Redefine(PIGMENT_ID_TOKEN))
  2953.         Destroy_Pigment((PIGMENT *)Constant_Ptr->Constant_Data);
  2954.       Local_Pigment = Copy_Pigment((Default_Texture->Pigment));
  2955.       Parse_Pigment (&Local_Pigment);
  2956.       Constant_Ptr -> Constant_Type = PIGMENT_CONSTANT;
  2957.       Constant_Ptr -> Constant_Data = (char *)Local_Pigment;
  2958.       EXIT
  2959.     END_CASE
  2960.  
  2961.     CASE (TNORMAL_TOKEN)
  2962.       if (Test_Redefine(TNORMAL_ID_TOKEN))
  2963.         Destroy_Tnormal((TNORMAL *)Constant_Ptr->Constant_Data);
  2964.       Local_Tnormal = Copy_Tnormal((Default_Texture->Tnormal));
  2965.       Parse_Tnormal (&Local_Tnormal);
  2966.       Constant_Ptr -> Constant_Type = TNORMAL_CONSTANT;
  2967.       Constant_Ptr -> Constant_Data = (char *) Local_Tnormal;
  2968.       EXIT
  2969.     END_CASE
  2970.  
  2971.     CASE (FINISH_TOKEN)
  2972.       if (Test_Redefine(FINISH_ID_TOKEN))
  2973.         Destroy_Finish((FINISH *)Constant_Ptr->Constant_Data);
  2974.       Local_Finish = Copy_Finish((Default_Texture->Finish));
  2975.       Parse_Finish (&Local_Finish);
  2976.       Constant_Ptr -> Constant_Type = FINISH_CONSTANT;
  2977.       Constant_Ptr -> Constant_Data = (char *) Local_Finish;
  2978.       EXIT
  2979.     END_CASE
  2980.  
  2981.     CASE (CAMERA_TOKEN)
  2982.       if (Test_Redefine(CAMERA_ID_TOKEN))
  2983.         Destroy_Camera((CAMERA *)Constant_Ptr->Constant_Data);
  2984.       Local_Camera = Copy_Camera(Default_Camera);
  2985.       Parse_Camera (&Local_Camera);
  2986.       Constant_Ptr -> Constant_Type = CAMERA_CONSTANT;
  2987.       Constant_Ptr -> Constant_Data = (char *) Local_Camera;
  2988.       EXIT
  2989.     END_CASE
  2990.  
  2991.     CASE (TEXTURE_TOKEN)
  2992.       if (Test_Redefine(TEXTURE_ID_TOKEN))
  2993.         Destroy_Textures((TEXTURE *)Constant_Ptr->Constant_Data);
  2994.       Local_Texture = Parse_Texture ();
  2995.       Constant_Ptr -> Constant_Type = TEXTURE_CONSTANT;
  2996.       Constant_Ptr -> Constant_Data = NULL;
  2997.       Link_Textures((TEXTURE **) &Constant_Ptr->Constant_Data, Local_Texture);
  2998.       EXPECT
  2999.         CASE (TEXTURE_TOKEN)
  3000.           Local_Texture = Parse_Texture ();
  3001.           Link_Textures((TEXTURE **) &Constant_Ptr->Constant_Data, Local_Texture);
  3002.         END_CASE
  3003.  
  3004.         OTHERWISE
  3005.           UNGET
  3006.           EXIT
  3007.         END_CASE
  3008.       END_EXPECT
  3009.       EXIT
  3010.     END_CASE
  3011.  
  3012.     CASE (COLOUR_MAP_TOKEN)
  3013.       if (Test_Redefine(COLOUR_MAP_ID_TOKEN))
  3014.         Destroy_Colour_Map((COLOUR_MAP *)Constant_Ptr->Constant_Data);
  3015.       Local_Colour_Map = Parse_Colour_Map ();
  3016.       Constant_Ptr -> Constant_Type = COLOUR_MAP_CONSTANT;
  3017.       Constant_Ptr -> Constant_Data = (char *) Local_Colour_Map;
  3018.       EXIT
  3019.     END_CASE
  3020.  
  3021.     CASE (TRANSFORM_TOKEN)
  3022.       if (Test_Redefine(TRANSFORM_ID_TOKEN))
  3023.         Destroy_Transform((TRANSFORM *)Constant_Ptr->Constant_Data);
  3024.       Local_Trans = Parse_Transform ();
  3025.       Constant_Ptr -> Constant_Type = TRANSFORM_CONSTANT;
  3026.       Constant_Ptr -> Constant_Data = (char *) Local_Trans;
  3027.       EXIT
  3028.     END_CASE
  3029.  
  3030.     OTHERWISE
  3031.       UNGET
  3032.       if (Test_Redefine(OBJECT_ID_TOKEN))
  3033.         Destroy_Object((OBJECT *)Constant_Ptr->Constant_Data);
  3034.       Local_Object = Parse_Object ();
  3035.       Constant_Ptr -> Constant_Type = OBJECT_CONSTANT;
  3036.       Constant_Ptr -> Constant_Data = (char *) Local_Object;
  3037.       EXIT
  3038.     END_CASE
  3039.  
  3040.   END_EXPECT
  3041.   }
  3042.  
  3043. static void Link (New_Object, Field, Old_Object_List)
  3044.   OBJECT *New_Object, **Field, **Old_Object_List;
  3045.   {
  3046.   *Field = *Old_Object_List;
  3047.   *Old_Object_List = New_Object;
  3048.   }
  3049.  
  3050. static void Link_Textures (Old_Textures, New_Textures)
  3051.   TEXTURE **Old_Textures;
  3052.   TEXTURE  *New_Textures;
  3053.   {
  3054.    TEXTURE *Layer;
  3055.  
  3056.    for (Layer = New_Textures ;
  3057.         Layer->Next_Layer != NULL ;
  3058.         Layer = Layer->Next_Layer)
  3059.      {}
  3060.         Layer->Next_Layer = *Old_Textures;
  3061.         *Old_Textures = New_Textures;
  3062.   }
  3063.  
  3064. static
  3065. char *Get_Token_String (Token_Id)
  3066.   TOKEN Token_Id;
  3067.   {
  3068.   register int i;
  3069.  
  3070.   for (i = 0 ; i < LAST_TOKEN ; i++)
  3071.      if (Reserved_Words[i].Token_Number == Token_Id)
  3072.         return (Reserved_Words[i].Token_Name);
  3073.   return ("");
  3074.   }
  3075.  
  3076. static
  3077. void Where_Error ()
  3078.   {
  3079.   fprintf (stderr, "\nError in file %s line %d\n", Token.Filename,
  3080.                                                  Token.Token_Line_No+1);
  3081.   }
  3082.  
  3083. static int Test_Redefine(a)
  3084.   int a;
  3085.   {
  3086.   char *old, *new;
  3087.  
  3088.   if (Previous == IDENTIFIER_TOKEN)
  3089.     return (FALSE);
  3090.   if (Previous != a)
  3091.     {old = Get_Token_String (Previous);
  3092.      new = Get_Token_String (a);
  3093.      Where_Error ();
  3094.      fprintf (stderr, "Attempted to redefine %s as %s", old, new);
  3095.      exit (1);
  3096.     }
  3097.   return (TRUE);
  3098.   }
  3099.  
  3100. void Parse_Error (Token_Id)
  3101.   TOKEN Token_Id;
  3102.   {
  3103.   char *expected;
  3104.  
  3105.   expected = Get_Token_String (Token_Id);
  3106.   Parse_Error_Str(expected);
  3107.   }
  3108.  
  3109. void Parse_Error_Str (str)
  3110.   char *str;
  3111.   {
  3112.    Where_Error ();
  3113.    fprintf (stderr, "%s expected but", str);
  3114.    Found_Instead ();
  3115.    exit (1);
  3116.   }
  3117.  
  3118. static void Found_Instead ()
  3119.   {
  3120.   char *found;
  3121.  
  3122.   if (Token.Token_Id == IDENTIFIER_TOKEN)
  3123.     fprintf (stderr,
  3124.       " undeclared identifier '%s' found instead.\n", Token.Token_String);
  3125.   else
  3126.    {
  3127.     found = Get_Token_String (Token.Token_Id);
  3128.     fprintf (stderr, " %s found instead.\n", found);
  3129.    }
  3130.   }
  3131. /*
  3132. static void Parse_Warn (Token_Id)
  3133.   TOKEN Token_Id;
  3134.   {
  3135.   char *expected;
  3136.  
  3137.   fprintf (stderr, "\nWarning in file %s line %d\n", Token.Filename,
  3138.                                                    Token.Token_Line_No+1);
  3139.   expected = Get_Token_String (Token_Id);
  3140.   fprintf (stderr, "%s expected but", expected);
  3141.   Found_Instead ();
  3142.   }
  3143. */
  3144. static void Warn_State (Token_Id,Type)
  3145.   TOKEN Token_Id, Type;
  3146.   {
  3147.   char *found;
  3148.   char *should;
  3149.  
  3150.   if (Language_Version < 1.5)
  3151.      return;
  3152.  
  3153.   fprintf (stderr, "\nWarning in file %s line %d\n", Token.Filename,
  3154.                                                    Token.Token_Line_No+1);
  3155.   found = Get_Token_String (Token_Id);
  3156.   should = Get_Token_String (Type);
  3157.   fprintf (stderr, "Found %s that should be in %s statement", found, should);
  3158.   }
  3159.  
  3160. void Warn (str,Level)
  3161.   char *str;
  3162.   DBL Level;
  3163.   {
  3164.   if (Language_Version < Level)
  3165.     return;
  3166.     
  3167.   fprintf (stdout, "\nWarning in file %s line %d\n", Token.Filename,
  3168.                                                    Token.Token_Line_No+1);
  3169.   fputs (str, stdout);
  3170.   }
  3171.  
  3172. void Error (str)
  3173.   char *str;
  3174.   {
  3175.   Where_Error ();
  3176.   fputs (str, stderr);
  3177.   exit (1);
  3178.   }
  3179.  
  3180. void MAError (str)
  3181.   char *str;
  3182.   {
  3183.   Where_Error ();
  3184.   fprintf (stderr, "Out of memory.  Cannot allocate %s.\n",str);
  3185.   exit (1);
  3186.   }
  3187.  
  3188. /* Write a token out to the token file */
  3189.  
  3190. void Write_Token (Token_Id, Data_File)
  3191.   TOKEN Token_Id;
  3192.   DATA_FILE *Data_File;
  3193.  
  3194.   {
  3195.    Token.Token_Id = Token_Id;
  3196.    Token.Token_Line_No = Data_File->Line_Number;
  3197.    Token.Filename = Data_File->Filename;
  3198.    Token.Token_String = String;
  3199.    Token.Constant_Data = NULL;
  3200.    Token.Constant_Index = (int) Token.Token_Id - (int) LAST_TOKEN;
  3201.  
  3202.    if (Token.Constant_Index >= 0)
  3203.      {if (Token.Constant_Index <= Number_Of_Constants)
  3204.         {Token.Constant_Data = Constants[Token.Constant_Index].Constant_Data;
  3205.          switch (Constants[Token.Constant_Index].Constant_Type)
  3206.            {CASEID(COLOUR_CONSTANT,     COLOUR_ID_TOKEN)
  3207.             CASEID(VECTOR_CONSTANT,     VECTOR_ID_TOKEN)
  3208.             CASEID(FLOAT_CONSTANT,      FLOAT_ID_TOKEN)
  3209.             CASEID(PIGMENT_CONSTANT,    PIGMENT_ID_TOKEN)
  3210.             CASEID(TNORMAL_CONSTANT,    TNORMAL_ID_TOKEN)
  3211.             CASEID(FINISH_CONSTANT,     FINISH_ID_TOKEN)
  3212.             CASEID(TEXTURE_CONSTANT,    TEXTURE_ID_TOKEN)
  3213.             CASEID(OBJECT_CONSTANT,     OBJECT_ID_TOKEN)
  3214.             CASEID(COLOUR_MAP_CONSTANT, COLOUR_MAP_ID_TOKEN)
  3215.             CASEID(TRANSFORM_CONSTANT,  TRANSFORM_ID_TOKEN)
  3216.             CASEID(CAMERA_CONSTANT,     CAMERA_ID_TOKEN)
  3217.            }
  3218.         }
  3219.       else Token.Token_Id = IDENTIFIER_TOKEN;
  3220.      }
  3221.   }
  3222.  
  3223. static void Post_Process (Object,Parent)
  3224.   OBJECT *Object, *Parent;
  3225.   {
  3226.    OBJECT *Sib;
  3227.  
  3228.    if (Object == NULL)
  3229.      return;
  3230.  
  3231.    if (Parent != NULL)
  3232.      {
  3233.       if (Object->Texture == NULL)
  3234.         Object->Texture = Parent->Texture;
  3235. /*
  3236.       else
  3237.         if (Parent->Texture != NULL)
  3238.           {Local_Texture = Copy_Textures (Parent->Texture);
  3239.            Link_Textures (&(Object->Texture), Local_Texture);
  3240.           }
  3241. */ /* Removed for backward compat with 1.0.  May put back in. CEY 12/92 */
  3242.       Object->No_Shadow_Flag |= Parent->No_Shadow_Flag;
  3243.      }
  3244.      
  3245.    if (     (Object->Texture == NULL) 
  3246.         && !(Object->Type & TEXTURED_OBJECT) 
  3247.         && !(Object->Type & LIGHT_SOURCE_OBJECT))
  3248.      Object->Texture = Copy_Textures(Default_Texture);
  3249.  
  3250.    if (Object->Type & COMPOUND_OBJECT)
  3251.      {
  3252.       if (Object->Type & LIGHT_SOURCE_OBJECT)
  3253.         {
  3254.          ((LIGHT_SOURCE *)Object)->Next_Light_Source = Frame.Light_Sources;
  3255.          Frame.Light_Sources = (LIGHT_SOURCE *)Object;
  3256.         }
  3257.       for (Sib = ((CSG *)Object)->Children;
  3258.            Sib != NULL;
  3259.            Sib = Sib->Sibling)
  3260.         Post_Process(Sib, Object);
  3261.      }
  3262.    else
  3263.      {
  3264.       if (Object->Texture == NULL)
  3265.         Object->Texture = Copy_Textures(Default_Texture);
  3266.       if (Object->Texture->Type == PNF_TEXTURE) 
  3267.         if (Object->Texture->Tnormal != NULL)
  3268.           Object->Type |= DOUBLE_ILLUMINATE;
  3269.      }
  3270.    Post_Textures (Object->Texture);
  3271.    if ((Object->Type & WATER_LEVEL_OK_OBJECT) &&
  3272.        (Object->Type & IS_CHILD_OBJECT))
  3273.      Object->Methods = &Csg_Height_Field_Methods;
  3274.   }
  3275.  
  3276. static void Destroy_Constants ()
  3277.   {
  3278.    int i;
  3279.    char *Ptr;
  3280.  
  3281.    for (i=1; i <= Number_Of_Constants; i++)
  3282.      {
  3283.       Ptr = Constants[i].Constant_Data;
  3284.       switch (Constants[i].Constant_Type)
  3285.         {
  3286.          case COLOUR_CONSTANT:
  3287.            Destroy_Colour((COLOUR *)Ptr);
  3288.            break;
  3289.          case VECTOR_CONSTANT:
  3290.            Destroy_Vector((VECTOR *)Ptr);
  3291.            break;
  3292.          case FLOAT_CONSTANT:
  3293.            Destroy_Float((DBL *)Ptr);
  3294.            break;
  3295.          case PIGMENT_CONSTANT:
  3296.            Destroy_Pigment((PIGMENT *)Ptr);
  3297.            break;
  3298.          case TNORMAL_CONSTANT:
  3299.            Destroy_Tnormal((TNORMAL *)Ptr);
  3300.            break;
  3301.          case FINISH_CONSTANT:
  3302.            Destroy_Finish((FINISH *)Ptr);
  3303.            break;
  3304.          case TEXTURE_CONSTANT:
  3305.            Destroy_Textures((TEXTURE *)Ptr);
  3306.            break;
  3307.          case OBJECT_CONSTANT:
  3308.            Destroy_Object((OBJECT *)Ptr);
  3309.            break;
  3310.          case COLOUR_MAP_CONSTANT:
  3311.            Destroy_Colour_Map((COLOUR_MAP *)Ptr);
  3312.            break;
  3313.          case TRANSFORM_CONSTANT:
  3314.            Destroy_Transform((TRANSFORM *)Ptr);
  3315.            break;
  3316.          case CAMERA_CONSTANT:
  3317.            Destroy_Camera((CAMERA *)Ptr);
  3318.            break;
  3319.         }
  3320.      }
  3321.   }
  3322.  
  3323. static void Link_To_Frame (Object)
  3324.  OBJECT *Object;
  3325.  {
  3326.   OBJECT *This_Sib, *Next_Sib;
  3327.   
  3328.   if ((Object->Methods != &CSG_Union_Methods) ||
  3329.       (Object->Bound != NULL) ||
  3330.       (Object->Clip != NULL) ||
  3331.       (!Use_Slabs))
  3332.     {
  3333.      Link(Object, &(Object -> Sibling), &(Frame.Objects));
  3334.      return;
  3335.     }
  3336.   
  3337.   for (This_Sib = ((CSG *)Object)->Children;
  3338.        This_Sib != NULL;
  3339.        This_Sib = Next_Sib)
  3340.        {
  3341.         Next_Sib = This_Sib->Sibling; /*L2F changes Sibling so save it */
  3342.         Link_To_Frame (This_Sib);
  3343.        }
  3344.   Object->Texture = NULL;
  3345.   Object->Sibling = NULL;
  3346.   ((CSG *)Object)->Children = NULL;
  3347.   Destroy_Object (Object);
  3348.  }
  3349.